如何在 React 应用程序中保持 document.title 的更新?
Posted
技术标签:
【中文标题】如何在 React 应用程序中保持 document.title 的更新?【英文标题】:How do I keep document.title updated in React app? 【发布时间】:2014-12-03 16:34:10 【问题描述】:由于 React 没有任何内置方法来管理 document.title
,我曾经将它设置在我的路由处理程序的 componentDidMount
中。
但是现在我需要根据异步获取的state
修改标题。我开始在 componentDidUpdate
中添加分配,但时不时我忘记将 document.title
分配到某些页面中,并且之前的标题一直存在,直到我终于注意到它。
理想情况下,我想要一种以声明方式表达document.title
的方式,而无需分配它。考虑到我希望能够在多个嵌套级别指定文档标题,某种“假”组件可能最方便:
附加要求:
子项中指定的标题应覆盖父项指定的标题; 可靠(保证在更改路线时进行清理); 不应发出任何 DOM(即,没有 hack 组件返回<noscript>
);
我正在使用 react-router,但如果此组件也可以与其他路由器一起使用会更好。
有什么我可以用的吗?
【问题讨论】:
在你的渲染函数中有document.title = this.state.documentTitle
有什么问题?或者先检查更改做类似的事情。
@Mike:首先,您不应该在render
中这样做,它应该没有副作用。你的意思可能是componentDidUpdate
。好吧,随着应用程序的增长,如果您希望它出现在某些屏幕上,那么保持document.title
的一致性变得越来越困难,但对其他屏幕使用一些默认标题。只需要一页就忘记指定标题,它会变得陈旧。
【参考方案1】:
与此同时,3 年过去了! ;-) 如果您想操作除标题之外的其他页眉(如描述、规范等),react-document-meta NPM 依赖可能是一个不错的选择。
【讨论】:
【参考方案2】:class Layout extends React.Component
constructor(props)
super(props);
document.title = this.props.title;
render()
return(
<div>
</div>
);
然后<Layout title="My Title"/>
就这么简单!
【讨论】:
【参考方案3】:看看 NFL 的react-helmet。
【讨论】:
react-helmet 太棒了!【参考方案4】:试试react-frozenhead,它实际上比 react-document-title 更复杂 - 它允许我们更改标题、描述和部分中的任何其他内容。
【讨论】:
【参考方案5】:我为此写了react-document-title。
它提供了一种在单页应用程序中指定document.title
的声明方式。
如果您想在将组件渲染为字符串后在服务器上获取标题,请调用DocumentTitle.rewind()
。
特点
不发出 DOM,甚至不发出<noscript>
;
与普通的 React 组件一样,可以使用其父级的 props
和 state
;
可以在整个应用程序的许多地方定义;
支持任意级别的嵌套,因此您可以定义应用范围和页面特定的标题;
适用于客户端和服务器。
示例
假设你使用类似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>
);
);
来源
我会跟踪已挂载的实例,并且仅在更新、挂载或卸载时使用分配给已挂载实例堆栈顶部 DocumentTitle
的 title
。在服务器上,componentWillMount
会触发,但我们不会得到didMount
或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;
【讨论】:
亲爱的投票者,您能否提出解决此问题的其他解决方案? 这个 npm 包仍然可以用来设置文档标题吗?我正在使用 React 15.1.0。以上是关于如何在 React 应用程序中保持 document.title 的更新?的主要内容,如果未能解决你的问题,请参考以下文章
在 React.JS 中刷新后,如何让用户保持登录到 firebase?
Rails+React/Next.js:如何存储代码块以保持格式化?
如何在 React 和 Redux 中保持用户登录,使用 JWT 表达后端应用程序并且没有像 redux-persist 这样的包?
如何使用 aws amplify 保持用户登录 react-native