Faites défiler vers le haut de la page après rendu dans react.js
J'ai un problème, que je n'ai aucune idée, comment résoudre. Dans mon composant react, j'affiche une longue liste de données et quelques liens en bas. Après avoir cliqué sur l'un de ces liens, je remplis la liste avec une nouvelle collection de liens et je dois faire défiler vers le haut.
Le problème est comment faire défiler vers le haut après nouvelle collection est rendue?
'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;
14 réponses
Enfin.. J'ai utilisé:
componentDidMount() {
window.scrollTo(0, 0)
}
, j'ai résolu ce problème en ajoutant:
componentDidUpdate() {
ReactDOM.findDOMNode(this).scrollTop = 0
},
Vous pourriez utiliser quelque chose comme ça. ReactDom est pour réagir.14. Juste Réagir autrement.
componentDidUpdate = () => { ReactDom.findDOMNode(this).scrollIntoView(); }
Cela pourrait, et devrait probablement, être géré en utilisant refs :
"... vous pouvez utiliser ReactDOM.findDOMNode comme une "trappe d'échappement" mais nous ne le recommandons pas car il casse l'encapsulation et dans presque tous les cas, il existe un moyen plus clair de structurer votre code dans le modèle React."
Exemple de code:
class MyComponent extends React.Component {
componentDidMount() {
this._div.scrollTop = 0
}
render() {
return <div ref={(ref) => this._div = ref} />
}
}
Vous pouvez le faire dans le routeur comme ça:
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'));
Le onUpdate={() => window.scrollTo(0, 0)}
Mettre le haut de défilement.
Pour plus d'informations, consultez: http://codepen.io/Yuschick/post/react-reset-scroll-position-when-changing-routes
Vous pouvez simplement utiliser cela:
componentDidMount() {
window.scrollTo(0,0);
}
J'utilise le composant react-router ScrollToTop dont le code est décrit dans les documents react-router
Https://reacttraining.com/react-router/web/guides/scroll-restoration/scroll-to-top
Je change de code dans un fichier de Routes unique et après cela, pas besoin de changer de code dans chaque composant.
Exemple De Code -
Étape 1-Créer ScrollToTop.js Composant
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)
Étape 2-Dans L'Application.fichier js, ajouter le composant ScrollToTop après <Router
const App = () => (
<Router>
<ScrollToTop>
<App/>
</ScrollToTop>
</Router>
)
Voici encore une autre approche qui vous permet de choisir les composants montés sur lesquels vous souhaitez réinitialiser la position de défilement de la fenêtre sans dupliquer en masse ComponentDidUpdate/ComponentDidMount.
L'exemple ci-dessous encapsule le composant Blog avec ScrollIntoView(), de sorte que si l'itinéraire change lorsque le composant Blog est monté, alors ComponentDidUpdate du HOC mettra à jour la position de défilement de la fenêtre.
, Vous pouvez facilement enrouler sur l'ensemble de l'application, de sorte que tout changement d'itinéraire déclenchera une réinitialisation de la fenêtre.
Les Itinéraires.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>
);
ScrollIntoView.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { withRouter } from 'react-router';
export default (WrappedComponent) => {
class ResetWindowScroll extends Component {
componentDidUpdate = (prevProps) => {
this.props.location !== prevProps.location && window.scrollTo(0,0);
}
render = () => ( <WrappedComponent {...this.props} /> )
}
return withRouter(ResetWindowScroll);
}
C'est la seule chose qui a fonctionné pour moi (avec un composant de classe ES6):
componentDidMount() {
ReactDOM.findDOMNode(this).scrollIntoView();
}
Dans React Routing, il y a le problème que si nous redirigeons vers la nouvelle route, cela ne vous mènera pas automatiquement en haut de la page.
Même moi, j'ai eu le même problème.
Je viens d'ajouter la seule ligne à mon composant et cela a fonctionné comme du beurre.
componentDidMount() {
window.scrollTo(0, 0);
}
Voir: https://reacttraining.com/react-router/web/guides/scroll-restoration/scroll-to-top
Tout ce qui précède n'a pas fonctionné pour moi-Je ne sais pas pourquoi mais:
componentDidMount(){
document.getElementById('HEADER').scrollIntoView();
}
Travaillé, où HEADER est l'id de mon élément d'en-tête
Si vous faites cela pour mobile, au moins avec google chrome, vous verrez une barre blanche en bas.
Cela se produit lorsque la barre D'URL disparaît. Solution:
Modifier le css pour hauteur/min-hauteur: 100% à hauteur/min-hauteur: 100vh.
Https://developers.google.com/web/updates/2016/12/url-bar-resizing
CE code provoquera un comportement fluide sur le défilement :
<div onClick={() => {
ReactDOM.findDOMNode(this.headerRef)
.scrollIntoView({behavior: "smooth"});
}}
className='go-up-button' >
</div>
Vous pouvez passer d'autres paramètres dans le scrollIntoView() Syntaxe suivante peut être utilisée:
element.scrollIntoView();
element.scrollIntoView(alignToTop); // Boolean parameter
element.scrollIntoView(scrollIntoViewOptions); // Object parameter
alignToTop Facultatif Est une valeur booléenne:
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 Facultatif Est un Objet avec les propriétés suivantes:
*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".
Plus de détails peuvent être trouvés ici: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
Quelque chose comme ça a fonctionné pour moi sur un composant:
<div ref="scroller" style={{height: 500, overflowX: "hidden", overflowY: "auto"}}>
//Content Here
</div>
Alors dans n'importe quelle fonction traite des mises à jour:
this.refs.scroller.scrollTop=0