react connected javascript reactjs react-router react-router-redux

javascript - connected - reaccionar-enrutador desplaza hacia arriba en cada transición



react-router-redux npm (10)

Tengo un problema al navegar en otra página, su posición se mantendrá como la página anterior. Por lo tanto, no se desplazará automáticamente a la parte superior. También he intentado usar window.scrollTo(0, 0) en el enrutador onChange. También he usado scrollBehavior para solucionar este problema, pero no funcionó. ¿Alguna sugerencia sobre esto?


Aquí hay otro método.

Para react-router v4 , también puede vincular a un oyente para que cambie el evento histórico de la siguiente manera:

let firstMount = true; const App = (props) => { if (typeof window != ''undefined'') { //incase you have server-side rendering too firstMount && props.history.listen((location, action) => { setImmediate(() => window.scrollTo(0, 0)); // ive explained why i used setImmediate below }); firstMount = false; } return ( <div> <MyHeader/> <Switch> <Route path=''/'' exact={true} component={IndexPage} /> <Route path=''/other'' component={OtherPage} /> // ... </Switch> <MyFooter/> </div> ); } //mounting app: render((<BrowserRouter><Route component={App} /></BrowserRouter>), document.getElementById(''root''));

El nivel de desplazamiento se establecerá en 0 sin setImmediate() también si se cambia la ruta haciendo clic en un enlace, pero si el usuario presiona el botón de retroceso en el navegador, entonces no funcionará ya que el navegador restablece el nivel de desplazamiento manualmente al nivel anterior cuando el respaldo se presiona el botón, por lo que al usar setImmediate() hacemos que nuestra función se ejecute después de que el navegador haya terminado de restablecer el nivel de desplazamiento, lo que nos da el efecto deseado.


Con React Router Dom V4 puedes usar

crear un componente scrollToTopComponent como el de abajo

class ScrollToTop extends Component { componentDidUpdate(prevProps) { if (this.props.location !== prevProps.location) { window.scrollTo(0, 0) } } render() { return this.props.children } } export default withRouter(ScrollToTop)

o si está utilizando pestañas use algo como el de abajo

class ScrollToTopOnMount extends Component { componentDidMount() { window.scrollTo(0, 0) } render() { return null } } class LongContent extends Component { render() { <div> <ScrollToTopOnMount/> <h1>Here is my long content page</h1> </div> } } // somewhere else <Route path="/long-content" component={LongContent}/>

Espero que esto ayude a obtener más información sobre la restauración de desplazamiento.


Encontré que ReactDOM.findDomNode(this).scrollIntoView() está funcionando. Lo coloqué dentro de componentDidMount() .


Es onUpdate={() => window.scrollTo(0, 0)} que el onUpdate={() => window.scrollTo(0, 0)} está desactualizado.

Aquí hay una solución simple para reaccion-router 4+.

const history = createBrowserHistory() history.listen(_ => { window.scrollTo(0, 0) }) <Router history={history}>


Escribí un componente de orden superior llamado withScrollToTop . Este HOC lleva en dos banderas:

  • onComponentWillMount : si se desplaza hacia arriba al navegar ( componentWillMount )
  • onComponentDidUpdate : si se desplaza hacia arriba después de la actualización ( componentDidUpdate ). Este indicador es necesario en los casos en que el componente no está desmontado pero ocurre un evento de navegación, por ejemplo, desde /users/1 a /users/2 .

// @flow import type { Location } from ''react-router-dom''; import type { ComponentType } from ''react''; import React, { Component } from ''react''; import { withRouter } from ''react-router-dom''; type Props = { location: Location, }; type Options = { onComponentWillMount?: boolean, onComponentDidUpdate?: boolean, }; const defaultOptions: Options = { onComponentWillMount: true, onComponentDidUpdate: true, }; function scrollToTop() { window.scrollTo(0, 0); } const withScrollToTop = (WrappedComponent: ComponentType, options: Options = defaultOptions) => { return class withScrollToTopComponent extends Component<Props> { props: Props; componentWillMount() { if (options.onComponentWillMount) { scrollToTop(); } } componentDidUpdate(prevProps: Props) { if (options.onComponentDidUpdate && this.props.location.pathname !== prevProps.location.pathname) { scrollToTop(); } } render() { return <WrappedComponent {...this.props} />; } }; }; export default (WrappedComponent: ComponentType, options?: Options) => { return withRouter(withScrollToTop(WrappedComponent, options)); };

Para usarlo:

import withScrollToTop from ''./withScrollToTop''; function MyComponent() { ... } export default withScrollToTop(MyComponent);


Esto es hacky (pero funciona): acabo de añadir

window.scrollTo (0,0);

hacer ();


La documentación para React Router v4 contiene ejemplos de código para la restauración de desplazamiento. Aquí está su primer ejemplo de código, que sirve como una solución para todo el sitio para "desplazarse hacia arriba" cuando se navega una página para:

class ScrollToTop extends Component { componentDidUpdate(prevProps) { if (this.props.location !== prevProps.location) { window.scrollTo(0, 0) } } render() { return this.props.children } } export default withRouter(ScrollToTop)

Luego, colóquelo en la parte superior de su aplicación, pero debajo de Router:

const App = () => ( <Router> <ScrollToTop> <App/> </ScrollToTop> </Router> ) // or just render it bare anywhere you want, but just one :) <ScrollToTop/>

^ Copiado directamente de la documentación.

Obviamente, esto funciona para la mayoría de los casos, pero hay más información sobre cómo manejar las interfaces con pestañas y por qué no se ha implementado una solución genérica.


Para react-router v4 , aquí hay una aplicación crear-reaccionar que logra la restauración de desplazamiento: http://router-scroll-top.surge.sh/ .

Para lograr esto, puede crear decorar el componente Route y aprovechar los métodos de ciclo de vida:

import React, { Component } from ''react''; import { Route, withRouter } from ''react-router-dom''; class ScrollToTopRoute extends Component { componentDidUpdate(prevProps) { if (this.props.path === this.props.location.pathname && this.props.location.pathname !== prevProps.location.pathname) { window.scrollTo(0, 0) } } render() { const { component: Component, ...rest } = this.props; return <Route {...rest} render={props => (<Component {...props} />)} />; } } export default withRouter(ScrollToTopRoute);

En el componentDidUpdate podemos verificar cuándo cambia la ruta de acceso de la ubicación y hacerla coincidir con la path y, si están satisfechos, restaurar el desplazamiento de la ventana.

Lo bueno de este enfoque es que podemos tener rutas que restauran el desplazamiento y las rutas que no lo hacen.

Aquí hay un ejemplo de App.js de cómo puedes usar lo anterior:

import React, { Component } from ''react''; import { BrowserRouter as Router, Route, Link } from ''react-router-dom''; import Lorem from ''react-lorem-component''; import ScrollToTopRoute from ''./ScrollToTopRoute''; import ''./App.css''; const Home = () => ( <div className="App-page"> <h2>Home</h2> <Lorem count={12} seed={12} /> </div> ); const About = () => ( <div className="App-page"> <h2>About</h2> <Lorem count={30} seed={4} /> </div> ); const AnotherPage = () => ( <div className="App-page"> <h2>This is just Another Page</h2> <Lorem count={12} seed={45} /> </div> ); class App extends Component { render() { return ( <Router> <div className="App"> <div className="App-header"> <ul className="App-nav"> <li><Link to="/">Home</Link></li> <li><Link to="/about">About</Link></li> <li><Link to="/another-page">Another Page</Link></li> </ul> </div> <Route exact path="/" component={Home} /> <ScrollToTopRoute path="/about" component={About} /> <ScrollToTopRoute path="/another-page" component={AnotherPage} /> </div> </Router> ); } } export default App;

Del código anterior, lo que es interesante señalar es que solo cuando se navega a /about o /another-page la acción de desplazamiento hacia arriba se realizará. Sin embargo, al continuar / no se producirá la restauración de desplazamiento.

El código base completo se puede encontrar aquí: https://github.com/rizedr/react-router-scroll-top


Tuve el mismo problema con mi aplicación. El uso del siguiente fragmento de código me ayudó a desplazarme hasta la parte superior de la página al hacer clic en el siguiente botón.

<Router onUpdate={() => window.scrollTo(0, 0)} history= {browserHistory}> ... </Router>

Sin embargo, el problema aún persistía en el navegador. Después de muchas pruebas, me di cuenta de que esto se debía al objeto histórico de la ventana del navegador, que tiene una propiedad scrollRestoration que se configuró en automático. Configurar esto en manual resolvió mi problema.

function scrollToTop() { window.scrollTo(0, 0) if (''scrollRestoration'' in history) { history.scrollRestoration = ''manual''; } } <Router onUpdate= {scrollToTop} history={browserHistory}> .... </Router>


Esta respuesta es para el código heredado, para el enrutador v4 + verifique otras respuestas

<Router onUpdate={() => window.scrollTo(0, 0)} history={createBrowserHistory()}> ... </Router>

Si no está funcionando, deberías encontrar la razón. También dentro de componentDidMount

document.body.scrollTop = 0; // or window.scrollTo(0,0);

usted podría utilizar:

componentDidUpdate() { window.scrollTo(0,0); }

podría agregar alguna marca como "scrolled = false" y luego en la actualización:

componentDidUpdate() { if(this.scrolled === false){ window.scrollTo(0,0); scrolled = true; } }