javascript 如何在 React 应用程序中保持 document.title 更新?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26266675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I keep document.title updated in React app?
提问by Dan Abramov
Since React doesn't have any builtin way to manage document.title
, I used to set it inside componentDidMount
of my route handlers.
由于 React 没有任何内置方式来管理document.title
,我曾经在componentDidMount
我的路由处理程序中设置它。
However now I need to amend the title based on state
fetched asynchronously. I started putting assingments into componentDidUpdate
, but every now and then I forget to put document.title
assignment into some pages, and previous title sticks around until I finally notice it.
但是现在我需要根据state
异步获取来修改标题。我开始把assingments成componentDidUpdate
,但每一个现在,然后我忘了把document.title
分配到一些网页,和周围,直到我终于发现它以前的标题棒。
Ideally I'd like a way to express document.title
declaratively, without having to assign it. Some kind of “fake” component would probably be most convenient, given that I want to be able to specify the document title at several nesting levels:
理想情况下,我想要一种document.title
无需分配即可声明式表达的方式。考虑到我希望能够在多个嵌套级别指定文档标题,某种“假”组件可能是最方便的:
- On top level (the default title);
- On page level (for some of the pages, but not all);
- Sometimes, on inner component level (e.g. user typing into a field).
- 在顶层(默认标题);
- 在页面级别(对于某些页面,但不是全部);
- 有时,在内部组件级别(例如用户输入字段)。
Additional requirements:
其他要求:
- Title specified in child should override title specified by parent;
- Reliable (guarantees cleanup on route change);
- Should not emit any DOM (i.e. no hacks with component returning
<noscript>
); - I'm using react-router but it's better if this component works with other routers too.
- child 中指定的 title 应该覆盖 parent 中指定的 title;
- 可靠(保证路线改变时的清理);
- 不应发出任何 DOM(即没有组件返回的 hacks
<noscript>
); - 我正在使用 react-router 但如果这个组件也能与其他路由器一起使用会更好。
Anything I can use?
有什么我可以用的吗?
回答by Dan Abramov
I wrote react-document-titlejust for that.
我为此编写了react-document-title。
It provides a declarative way to specify document.title
in a single-page app.
If you want to get title on server after rendering components to string, call DocumentTitle.rewind()
.
它提供了一种document.title
在单页应用程序中指定的声明方式。
如果您想在将组件渲染为字符串后在服务器上获得标题,请调用DocumentTitle.rewind()
.
Features
特征
- Does not emit DOM, not even a
<noscript>
; - Like a normal React compoment, can use its parent's
props
andstate
; - Can be defined in many places throughout the application;
- Supports arbitrary levels of nesting, so you can define app-wide and page-specific titles;
- Works on client and server.
- 不发出 DOM,甚至不发出
<noscript>
; - 像普通的 React 组件一样,可以使用其父级的
props
andstate
; - 可以在整个应用程序的很多地方定义;
- 支持任意级别的嵌套,因此您可以定义应用程序范围和页面特定的标题;
- 适用于客户端和服务器。
Example
例子
Assuming you use something like react-router:
假设你使用类似react-router 的东西:
var App = React.createClass({
render: function () {
// Use "My Web App" if no child overrides this
return (
<DocumentTitle title='My Web App'>
<this.props.activeRouteHandler />
</DocumentTitle>
);
}
});
var HomePage = React.createClass({
render: function () {
// Use "Home" while this component is mounted
return (
<DocumentTitle title='Home'>
<h1>Home, sweet home.</h1>
</DocumentTitle>
);
}
});
var NewArticlePage = React.createClass({
mixins: [LinkStateMixin],
render: function () {
// Update using value from state while this component is mounted
return (
<DocumentTitle title={this.state.title || 'Untitled'}>
<div>
<h1>New Article</h1>
<input valueLink={this.linkState('title')} />
</div>
</DocumentTitle>
);
}
});
Source
来源
I keep track of mounted instances and only use title
given to the top DocumentTitle
in the mounted instance stack whenever it updates, gets mounted or unmounted. On server, componentWillMount
fires but we won't get didMount
or willUnmount
, so we introduce DocumentTitle.rewind()
that returns a string and destroys state to prepare for next request.
我跟踪已安装的实例,并且仅在它更新、安装或卸载时才使用已安装实例堆栈中title
的顶部DocumentTitle
。在服务器上,componentWillMount
触发但我们不会得到didMount
or willUnmount
,因此我们引入DocumentTitle.rewind()
返回一个字符串并破坏状态以准备下一个请求。
var DocumentTitle = React.createClass({
propTypes: {
title: PropTypes.string
},
statics: {
mountedInstances: [],
rewind: function () {
var activeInstance = DocumentTitle.getActiveInstance();
DocumentTitle.mountedInstances.splice(0);
if (activeInstance) {
return activeInstance.props.title;
}
},
getActiveInstance: function () {
var length = DocumentTitle.mountedInstances.length;
if (length > 0) {
return DocumentTitle.mountedInstances[length - 1];
}
},
updateDocumentTitle: function () {
if (typeof document === 'undefined') {
return;
}
var activeInstance = DocumentTitle.getActiveInstance();
if (activeInstance) {
document.title = activeInstance.props.title;
}
}
},
getDefaultProps: function () {
return {
title: ''
};
},
isActive: function () {
return this === DocumentTitle.getActiveInstance();
},
componentWillMount: function () {
DocumentTitle.mountedInstances.push(this);
DocumentTitle.updateDocumentTitle();
},
componentDidUpdate: function (prevProps) {
if (this.isActive() && prevProps.title !== this.props.title) {
DocumentTitle.updateDocumentTitle();
}
},
componentWillUnmount: function () {
var index = DocumentTitle.mountedInstances.indexOf(this);
DocumentTitle.mountedInstances.splice(index, 1);
DocumentTitle.updateDocumentTitle();
},
render: function () {
if (this.props.children) {
return Children.only(this.props.children);
} else {
return null;
}
}
});
module.exports = DocumentTitle;
回答by dbkaplun
Take a look at the NFL's react-helmet.
看看 NFL 的react-helmet。
回答by rajesh_kw
class Layout extends React.Component {
constructor(props){
super(props);
document.title = this.props.title;
}
render(){
return(
<div>
</div>
);
}
}
and then <Layout title="My Title"/>
that easy!
然后就<Layout title="My Title"/>
这么简单!
回答by Vadim Guzev
Try react-frozenhead, it's actually more sophisticated than react-document-title - it allows us change title, description and anything else in section.
尝试react-frozenhead,它实际上比 react-document-title 更复杂 - 它允许我们更改部分中的标题、描述和其他任何内容。
回答by Pedro Ferreira
Meanwhile, 3 years have gone! ;-)
If you want to manipulate other page headers than title (like description, canonical, etc.), react-document-metaNPM dependency could be a good thing to use.
与此同时,3年过去了!;-)
如果你想操作除标题之外的其他页眉(如描述、规范等),react-document-metaNPM 依赖可能是一个很好的选择。