Étant donné que React n’a aucun moyen intégré de gérer document.title
, j’ai l'habitude de le définir dans componentDidMount
de mes gestionnaires d'itinéraire.
Cependant, je dois maintenant modifier le titre en fonction de state
récupéré de manière asynchrone. J'ai commencé à mettre des évaluations dans componentDidUpdate
, mais de temps en temps, j'oublie de mettre une affectation document.title
dans certaines pages et le titre précédent reste visible jusqu'à ce que je le remarque enfin.
Idéalement, je voudrais un moyen d’exprimer document.title
de manière déclarative, sans avoir à l’affecter. Une sorte de "faux" composant serait probablement plus pratique, étant donné que je veux pouvoir spécifier le titre du document à plusieurs niveaux d'imbrication:
Exigences supplémentaires:
<noscript>
);Tout ce que je peux utiliser?
J'ai écrit react-document-title juste pour ça.
Il fournit un moyen déclaratif de spécifier document.title
dans une application à page unique.
Si vous souhaitez obtenir le titre sur le serveur après le rendu des composants en chaîne, appelez DocumentTitle.rewind()
.
<noscript>
;props
et state
de son parent;En supposant que vous utilisiez quelque chose comme 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>
);
}
});
Je garde une trace des instances montées et n'utilise que title
donné à la DocumentTitle
supérieure dans la pile d'instances montées à chaque mise à jour, montée ou démontée. Sur le serveur, componentWillMount
se déclenche mais nous n'obtiendrons pas didMount
ou willUnmount
; nous introduisons donc DocumentTitle.rewind()
qui renvoie une chaîne et détruit l'état pour préparer la prochaine requête.
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;
Jetez un coup d'œil au casque de la NFL .
class Layout extends React.Component {
constructor(props){
super(props);
document.title = this.props.title;
}
render(){
return(
<div>
</div>
);
}
}
et puis <Layout title="My Title"/>
aussi facile!
Essayez react-frozenhead , il est en réalité plus sophistiqué que react-document-title - cela nous permet de changer le titre, la description et tout autre élément de la section.
En attendant, 3 ans sont passés! ;-)
Si vous souhaitez manipuler d’autres en-têtes de page que le titre (comme la description, les noms canoniques, etc.), la dépendance react-document-meta NPM peut être une bonne chose.