tutorial reactdom react event div bottom scroll reactjs render

reactdom - scroll react js



Desplácese hasta la parte superior de la página después de renderizar en react.js (17)

Tengo un problema, que no tengo ideas, cómo resolverlo. En mi componente reaccionar, muestro una larga lista de datos y pocos enlaces en la parte inferior. Después de hacer clic en cualquiera de estos enlaces, completo la lista con una nueva colección de enlaces y necesito desplazarme hacia la parte superior.

El problema es: ¿cómo desplazarse hasta la parte superior después de que se renderice la nueva colección?

''use strict''; // url of this component is #/:checklistId/:sectionId var React = require(''react''), Router = require(''react-router''), sectionStore = require(''./../stores/checklist-section-store''); function updateStateFromProps() { var self = this; sectionStore.getChecklistSectionContent({ checklistId: this.getParams().checklistId, sectionId: this.getParams().sectionId }).then(function (section) { self.setState({ section, componentReady: true }); }); this.setState({componentReady: false}); } var Checklist = React.createClass({ mixins: [Router.State], componentWillMount: function () { updateStateFromProps.call(this); }, componentWillReceiveProps(){ updateStateFromProps.call(this); }, render: function () { if (this.state.componentReady) { return( <section className=''checklist-section''> <header className=''section-header''>{ this.state.section.name } </header> <Steps steps={ this.state.section.steps }/> <a href=`#/${this.getParams().checklistId}/${this.state.section.nextSection.Id}`> Next Section </a> </section> ); } else {...} } }); module.exports = Checklist;


Algo como esto me funcionó en un componente:

<div ref="scroller" style={{height: 500, overflowX: "hidden", overflowY: "auto"}}> //Content Here </div>

Luego, en cualquier función que se trate de actualizaciones:

this.refs.scroller.scrollTop=0


Aquí hay otro enfoque que le permite elegir qué componentes montados desea restablecer la posición de desplazamiento de la ventana sin duplicar en masa ComponentDidUpdate / ComponentDidMount.

El siguiente ejemplo está envolviendo el componente Blog con ScrollIntoView (), de modo que si la ruta cambia cuando se monta el componente Blog, ComponentDidUpdate del HOC actualizará la posición de desplazamiento de la ventana.

Puede envolverlo fácilmente en toda la aplicación, de modo que en cualquier cambio de ruta, se activará un reinicio de la ventana.

ScrollIntoView.js

import React, { Component } from ''react''; import { withRouter } from ''react-router''; export default WrappedComponent => { class ResetWindowScroll extends Component { componentDidUpdate = (prevProps) => { if(this.props.location !== prevProps.location) window.scrollTo(0,0); } render = () => <WrappedComponent {...this.props} /> } return withRouter(ResetWindowScroll); }

Routes.js

import React from ''react''; import { Route, IndexRoute } from ''react-router''; import App from ''../components/App''; import About from ''../components/pages/About''; import Blog from ''../components/pages/Blog'' import Index from ''../components/Landing''; import NotFound from ''../components/navigation/NotFound''; import ScrollIntoView from ''../components/navigation/ScrollIntoView''; export default ( <Route path="/" component={App}> <IndexRoute component={Index} /> <Route path="/about" component={About} /> <Route path="/blog" component={ScrollIntoView(Blog)} /> <Route path="*" component={NotFound} /> </Route> );

El ejemplo anterior funciona muy bien, pero si ha migrado a react-router-dom , puede simplificar lo anterior creando un HOC que envuelva el componente.

Una vez más, también podría envolverlo fácilmente en sus rutas (simplemente cambie el método componentDidMount al código de ejemplo del método componentDidUpdate escrito anteriormente, así como envolver ScrollIntoView con withRouter ).

contenedores / ScrollIntoView.js

import { PureComponent, Fragment } from "react"; class ScrollIntoView extends PureComponent { componentDidMount = () => window.scrollTo(0, 0); render = () => this.props.children } export default ScrollIntoView;

componentes / Home.js

import React from "react"; import ScrollIntoView from "../containers/ScrollIntoView"; export default () => ( <ScrollIntoView> <div className="container"> <p> Sample Text </p> </div> </ScrollIntoView> );


Dado que la solución original se proporcionó para una versión muy temprana de react , aquí hay una actualización:

constructor(props) { super(props) this.myRef = React.createRef() // Create a ref object } componentDidMount() { this.myRef.current.scrollTo(0, 0); } render() { return <div ref={this.myRef}></div> } // attach the ref property to a dom element


En React Routing existe el problema de que si redirigimos a la nueva ruta, no lo llevará automáticamente a la parte superior de la página.

Incluso yo tuve el mismo problema.

Acabo de agregar una sola línea a mi componente y funcionó como la mantequilla.

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

Consulte: reaccionar entrenamiento


Este código causará un comportamiento suave en el desplazamiento :

<div onClick={() => { ReactDOM.findDOMNode(this.headerRef) .scrollIntoView({behavior: "smooth"}); }} className=''go-up-button'' > </div>

Puede pasar otros parámetros dentro de scrollIntoView () Se puede usar la siguiente sintaxis:

element.scrollIntoView(); element.scrollIntoView(alignToTop); // Boolean parameter element.scrollIntoView(scrollIntoViewOptions); // Object parameter

alignToTop Opcional es un valor booleano:

If true, the top of the element will be aligned to the top of the visible area of the scrollable ancestor. Corresponds to scrollIntoViewOptions: {block: "start", inline: "nearest"}. This is the default value. If false, the bottom of the element will be aligned to the bottom of the visible area of the scrollable ancestor. Corresponds to scrollIntoViewOptions: {block: "end", inline: "nearest"}.

scrollIntoViewOptions Opcional Es un objeto con las siguientes propiedades:

*behavior* Optional Defines the transition animation. One of "auto", "instant", or "smooth". Defaults to "auto". *block* Optional One of "start", "center", "end", or "nearest". Defaults to "center". *inline* Optional One of "start", "center", "end", or "nearest". Defaults to "nearest".

Más detalles se pueden encontrar aquí: MDN docs


Esto es lo único que funcionó para mí (con un componente de clase ES6):

componentDidMount() { ReactDOM.findDOMNode(this).scrollIntoView(); }


Esto podría, y probablemente debería, manejarse usando refs :

"... puede usar ReactDOM.findDOMNode como una" escotilla de escape "pero no lo recomendamos ya que rompe la encapsulación y en casi todos los casos hay una forma más clara de estructurar su código dentro del modelo React".

Código de ejemplo:

class MyComponent extends React.Component { componentDidMount() { this._div.scrollTop = 0 } render() { return <div ref={(ref) => this._div = ref} /> } }


Estoy usando el componente ScrollToTop de react-router cuyo código se describe en los documentos de react-router

https://reacttraining.com/react-router/web/guides/scroll-restoration/scroll-to-top

Estoy cambiando el código en un solo archivo de rutas y después de eso no es necesario cambiar el código en cada componente.

Código de ejemplo -

Paso 1: crea el componente ScrollToTop.js

import React, { Component } from ''react''; import { withRouter } from ''react-router''; 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)

Paso 2: en el archivo App.js, agregue el componente ScrollToTop después de <Router

const App = () => ( <Router> <ScrollToTop> <App/> </ScrollToTop> </Router> )


Finalmente ... usé:

componentDidMount() { window.scrollTo(0, 0) }


Ninguna de las respuestas anteriores está funcionando actualmente para mí. Resulta que .scrollTo no es tan ampliamente compatible como .scrollIntoView .

En nuestro App.js, en componentWillMount() agregamos

this.props.history.listen((location, action) => { setTimeout(() => { document.getElementById(''root'').scrollIntoView({ behavior: "smooth" }) }, 777) })

Esta es la única solución que funciona universalmente para nosotros. root es la ID de nuestra aplicación. El comportamiento "fluido" no funciona en todos los navegadores / dispositivos. El tiempo de espera del 777 es un poco conservador, pero cargamos una gran cantidad de datos en cada página, por lo que fue necesario realizar pruebas. Un 237 más corto podría funcionar para la mayoría de las aplicaciones.


Ninguna de las respuestas anteriores está funcionando actualmente para mí. Resulta que .scrollTo no es tan ampliamente compatible como .scrollIntoView .

En nuestro App.js, en componentWillMount() agregamos

this.props.history.listen((location, action) => { setTimeout(() => { document.getElementById(''root'').scrollIntoView({ behavior: "smooth" }) }, 777) })

Esta es la única solución que funciona universalmente para nosotros. root es la ID de nuestra aplicación. El comportamiento "fluido" no funciona en todos los navegadores / dispositivos. El tiempo de espera del 777 es un poco conservador, pero cargamos una gran cantidad de datos en cada página, por lo que fue necesario realizar pruebas. Un 237 más corto podría funcionar para la mayoría de las aplicaciones.


Para aquellos que usan ganchos, el siguiente código funcionará.

componentDidMount(){ document.getElementById(''HEADER'').scrollIntoView(); }

Tenga en cuenta que también puede importar useEffect directamente: import { useEffect } from ''react''


Podrías usar algo como esto. ReactDom es para reaccionar.14. Solo reacciona de otra manera.

componentDidUpdate = () => { ReactDom.findDOMNode(this).scrollIntoView(); }

Actualización 5/11/2019 para React 16+

constructor(props) { super(props) this.childDiv = React.createRef() } componentDidMount = () => this.handleScroll() componentDidUpdate = () => this.handleScroll() handleScroll = () => { const { index, selected } = this.props if (index === selected) { setTimeout(() => { this.childDiv.current.scrollIntoView({ behavior: ''smooth'' }) }, 500) } }


Puede hacer esto en el enrutador así:

ReactDOM.render(( <Router onUpdate={() => window.scrollTo(0, 0)} history={browserHistory}> <Route path=''/'' component={App}> <IndexRoute component={Home}></IndexRoute> <Route path="/about" component={About}/> <Route path="/work"> <IndexRoute component={Work}></IndexRoute> <Route path=":id" component={ProjectFull}></Route> </Route> <Route path="/blog" component={Blog}/> </Route> </Router> ), document.getElementById(''root''));

onUpdate={() => window.scrollTo(0, 0)} coloca el desplazamiento arriba. Para más información consultar: enlace codepen


Si está haciendo esto para dispositivos móviles , al menos con Chrome, verá una barra blanca en la parte inferior.

Esto sucede cuando la barra de URL desaparece. Solución:

Cambie el css para height / min-height: 100% a height / min-height: 100vh .

Google Developer Docs


Todas las soluciones hablan de agregar el desplazamiento en componentDidMount o componentDidUpdate pero con el DOM.

Hice todo eso y no funcionó.

Entonces, descubrí otra forma que funciona bien para mí.

Se agregó componentDidUpdate() { window.scrollTo(0, 0) } en el encabezado, el mío está fuera del elemento <Switch></Switch> . Simplemente gratis en la aplicación. Trabajos.

También encontré algo sobre ScrollRestoration , pero ahora soy vago. Y por ahora lo mantendré al estilo "DidUpdate".

¡Espero eso ayude!

cuidate


Todo lo anterior no funcionó para mí, no estoy seguro de por qué, pero:

React.useEffect(() => { window.scrollTo(0, 0); }, []);

trabajado, donde HEADER es la identificación de mi elemento de encabezado