そのためだけにreact-document-titleを書きました。
document.title
シングルページ アプリで指定する宣言的な方法を提供します。
コンポーネントを文字列にレンダリングした後にサーバーでタイトルを取得する場合は、 を呼び出しますDocumentTitle.rewind()
。
特徴
- DOM も発行しません
<noscript>
。
- 通常の React コンポーネントと同様に、その親の
props
andを使用できます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>
);
}
});
ソース
マウントされたインスタンスを追跡し、更新、マウント、またはアンマウントされるたびに、マウントされたインスタンス スタックtitle
の一番上にあるものだけを使用します。DocumentTitle
サーバー上では、が発生しますが、または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;