Estoy buscando una forma de modificar el título de la página cuando React-Router v4+ cambia de ubicación. Solía escuchar una acción de cambio de ubicación en Redux y verificar esa ruta con un objeto de metaData .
Cuando se usa React-Router v4+, no hay una lista de rutas fijas. De hecho, varios componentes del sitio podrían usar Route con la misma cadena de ruta. Eso significa que el antiguo método que usé ya no funcionará.
¿Hay alguna manera de actualizar el título de la página llamando a acciones cuando se cambian ciertas rutas principales o hay un mejor método para actualizar los metadatos del sitio?
Los componentes <Route /> tienen propiedad de representación . Entonces puede modificar el título de la página cuando cambia la ubicación declarando sus rutas así:
<Route exact path="/" render={props => ( <Page {...props} component={Index} title="Index Page" /> )} /> <Route path="/about" render={props => ( <Page {...props} component={About} title="About Page" /> )} /> En el componente Page puede establecer el título de la ruta:
import React from "react" /* * Component which serves the purpose of a "root route component". */ class Page extends React.Component { /** * Here, we define a react lifecycle method that gets executed each time * our component is mounted to the DOM, which is exactly what we want in this case */ componentDidMount() { document.title = this.props.title } /** * Here, we use a component prop to render * a component, as specified in route configuration */ render() { const PageComponent = this.props.component return ( <PageComponent /> ) } } export default PageActualización 1 de agosto de 2019 . Esto solo funciona con react-router >= 4.x. Gracias a @supreme being7
Respuesta actualizada usando React Hooks :
Puede especificar el título de cualquier ruta usando el componente a continuación, que se construye usando useEffect .
import { useEffect } from "react"; const Page = (props) => { useEffect(() => { document.title = props.title || ""; }, [props.title]); return props.children; }; export default Page; Y luego usa Page en el render prop de una ruta:
<Route path="/about" render={(props) => ( <Page title="Index"> <Index {...props} /> </Page> )} /> <Route path="/profile" render={(props) => ( <Page title="Profile"> <Profile {...props} /> </Page> )} />En su método componentDidMount() haga esto para cada página
componentDidMount() { document.title = 'Your page title here'; }Esto cambiará el título de su página, haga lo mencionado anteriormente para cada ruta.
Además, si es más que solo la parte del título, verifique react-helmet Es una biblioteca muy ordenada para esto, y también maneja algunos casos de borde agradables.
Retomando la excelente respuesta de phen0menon , ¿por qué no extender Route en lugar de React.Component ?
import React, { useEffect } from 'react'; import { Route } from 'react-router-dom'; import PropTypes from 'prop-types'; export const Page = ({ title, ...rest }) => { useEffect(() => { document.title = title; }, [title]); return <Route {...rest} />; };Esto eliminará el código de sobrecarga como se ve a continuación:
// old: <Route exact path="/" render={props => ( <Page {...props} component={Index} title="Index Page" /> )} /> // improvement: <Page exact path="/" component={Index} title="Index Page" />Actualización: otra forma de hacerlo es con un gancho personalizado :
import { useEffect } from 'react'; /** Hook for changing title */ export const useTitle = title => { useEffect(() => { const oldTitle = document.title; title && (document.title = title); // following line is optional, but will reset title when component unmounts return () => document.title = oldTitle; }, [title]); };