Javascript 如何在React应用程序中更新document.title?
由于React没有任何内置的方法来管理Javascript 如何在React应用程序中更新document.title?,javascript,dom,reactjs,react-router,Javascript,Dom,Reactjs,React Router,由于React没有任何内置的方法来管理document.title,因此我习惯在路由处理程序的组件didmount中设置它 但是现在我需要根据异步获取的状态修改标题。我开始将作业放入组件diddupdate,但时不时我会忘记将文档、标题作业放入一些页面,之前的标题会一直保留,直到我最终注意到它 理想情况下,我希望能够以声明方式表达document.title,而不必指定它。考虑到我希望能够在多个嵌套级别指定文档标题,某种“伪”组件可能是最方便的: 在顶层(默认标题) 在页面级别(对于某些页面,
document.title
,因此我习惯在路由处理程序的组件didmount
中设置它
但是现在我需要根据异步获取的状态
修改标题。我开始将作业放入组件diddupdate
,但时不时我会忘记将文档、标题
作业放入一些页面,之前的标题会一直保留,直到我最终注意到它
理想情况下,我希望能够以声明方式表达document.title
,而不必指定它。考虑到我希望能够在多个嵌套级别指定文档标题,某种“伪”组件可能是最方便的:
- 在顶层(默认标题)李>
- 在页面级别(对于某些页面,但不是所有页面)李>
- 有时,在内部组件级别(例如,用户键入字段)
- 子项中指定的标题应覆盖父项指定的标题李>
- 可靠(保证路线变更时的清理)李>
- 不应发出任何DOM(即,没有组件返回的黑客攻击
)李> - 我正在使用react路由器,但如果这个组件也能与其他路由器一起工作,那就更好了
文档.标题。
如果要在将组件呈现为字符串后在服务器上获取标题,请调用DocumentTitle.rewind()
特征
- 不发出DOM,甚至不发出
李>
- 与普通React组件一样,可以使用其父级的
道具
和状态
李>
- 可以在整个应用程序的许多地方定义李>
- 支持任意级别的嵌套,因此您可以定义应用程序范围和页面特定的标题李>
- 在客户端和服务器上工作
例子
假设您使用类似于:
试试看,它实际上比react文档标题更复杂-它允许我们更改标题、描述和部分中的任何其他内容。看看NFL。类布局扩展react.Component{
建造师(道具){
超级(道具);
document.title=this.props.title;
}
render(){
返回(
);
}
}
然后
就这么简单了 同时,三年过去了
如果您想操作除标题以外的其他页面标题(如描述、规范等),NPM依赖关系可能是一个好方法。在呈现函数中使用document.title=this.state.documentTitle
有什么不对?或者先做一些类似的检查更改。@迈克:首先,你不应该在渲染中这样做,它应该没有副作用。您的意思可能是componentdiddupdate
。好吧,随着应用程序的发展,如果您希望在某些屏幕上显示document.title
,但在其他屏幕上使用一些默认标题,那么就很难保持一致。只需一页就可以忘记指定标题,这会变得过时。亲爱的downvoter,您是否可以建议另一种解决方案来解决此问题?此npm包是否仍然可以用于仅设置文档标题?我正在使用React 15.1.0。React-HELLAME太棒了!
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>
);
}
});
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;
class Layout extends React.Component {
constructor(props){
super(props);
document.title = this.props.title;
}
render(){
return(
<div>
</div>
);
}
}