J'ai un problème que je n'ai pas d'idées, comment résoudre . Dans mon composant de réaction, 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 le liste avec nouvelle collection de liens et besoin de 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;
La solution originale ayant été fournie pour la toute première version de react , voici une mise à jour:
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
Enfin .. j'ai utilisé:
componentDidMount() {
window.scrollTo(0, 0)
}
Vous pouvez utiliser quelque chose comme ça. ReactDom est pour react.14. Réagissez autrement.
componentDidUpdate = () => { ReactDom.findDOMNode(this).scrollIntoView(); }
Cela pourrait, et devrait probablement, être traité avec refs :
"... vous pouvez utiliser ReactDOM.findDOMNode en tant que" hachure d'échappement ", mais nous le déconseillons, 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 faire cela 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)}
a mis le parchemin en haut . Pour plus d'informations, consultez: codepen link
Dans React Routing, le problème est que si nous redirigeons vers le nouvel itinéraire, 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 ligne simple à mon composant et cela a fonctionné comme du beurre.
componentDidMount() {
window.scrollTo(0, 0);
}
Référez-vous: réagissez à la formation
J'utilise react-router ScrollToTop Component dont le code est décrit dans la documentation de react-router
https://reacttraining.com/react-router/web/guides/scroll-restoration/scroll-to-top
Je change de code dans un seul fichier Routes et ensuite, plus besoin de changer le code dans chaque composant.
Exemple de code -
Étape 1 - créer un composant 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)
Étape 2 - Dans le fichier App.js, ajoutez le composant ScrollToTop après <Router
const App = () => (
<Router>
<ScrollToTop>
<App/>
</ScrollToTop>
</Router>
)
Voici 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 englobe le composant Blog avec ScrollIntoView (). Ainsi, si la route change lorsque le composant Blog est monté, ComponentDidUpdate du HOC mettra à jour la position de défilement de la fenêtre.
Vous pouvez tout aussi facilement l'envelopper sur l'ensemble de l'application, de sorte que tout changement d'itinéraire entraîne une réinitialisation de la fenêtre.
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>
);
L'exemple ci-dessus fonctionne très bien, mais si vous avez migré vers react-router-dom
, vous pouvez le simplifier en créant un accessoire de rendu qui enveloppe le composant.
Encore une fois, vous pouvez également le recouvrir tout aussi facilement sur vos routes (il suffit de changer la méthode componentDidMount
en le code exemple de la méthode componentDidUpdate
écrit ci-dessus, ainsi que de recouvrir ScrollIntoView
avec withRouter
).
Exemple de travail: https://codesandbox.io/s/qq4x5x43k9 (cliquer seulement sur home pour mettre à jour la position de la fenêtre)
conteneurs/ScrollIntoView.js
import { PureComponent, Fragment } from "react";
class ScrollIntoView extends PureComponent {
componentDidMount = () => window.scrollTo(0, 0);
render = () => this.props.children
}
export default ScrollIntoView;
components/Home.js
import React from "react";
import ScrollIntoView from "../containers/ScrollIntoView";
export default () => (
<ScrollIntoView>
<div className="container">
<p>
Sample Text
</p>
</div>
</ScrollIntoView>
);
C'est la seule chose qui a fonctionné pour moi (avec un composant de classe ES6):
componentDidMount() {
ReactDOM.findDOMNode(this).scrollIntoView();
}
Pour ceux qui utilisent des hooks, le code suivant fonctionnera.
React.useEffect(() => {
window.scrollTo(0, 0);
}, []);
Notez que vous pouvez également importer directement useEffect: import { useEffect } from 'react'
Si vous faites cela pour mobile, au moins avec chrome, vous verrez une barre blanche en bas.
Cela se produit lorsque la barre d'URL disparaît. Solution:
Modifiez le css pour height/min-height: 100% en height/min-height: 100vh.
Aucune des réponses ci-dessus ne fonctionne actuellement pour moi. Il s'avère que .scrollTo
n'est pas aussi largement compatible que .scrollIntoView
.
Dans notre App.js, dans componentWillMount()
nous avons ajouté
this.props.history.listen((location, action) => {
setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777)
})
C’est la seule solution qui fonctionne universellement pour nous. root est l'ID de notre application. Le comportement "lisse" ne fonctionne pas sur tous les navigateurs/appareils. Le délai d'attente de 777 est un peu prudent, mais nous chargeons beaucoup de données sur chaque page, nous avons donc dû procéder à des tests. Un 237 plus court pourrait fonctionner pour la plupart des applications.
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'identifiant de mon en-tête
Aucune des réponses ci-dessus ne fonctionne actuellement pour moi. Il s'avère que .scrollTo
n'est pas aussi largement compatible que .scrollIntoView
.
Dans notre App.js, dans componentWillMount()
nous avons ajouté
this.props.history.listen((location, action) => {
setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777)
})
C’est la seule solution qui fonctionne universellement pour nous. root
est l'ID de notre application. Le comportement "lisse" ne fonctionne pas sur tous les navigateurs/appareils. Le délai d'attente de 777 est un peu prudent, mais nous chargeons beaucoup de données sur chaque page, nous avons donc effectué des tests. Un 237 plus court pourrait fonctionner pour la plupart des applications.
Ce code provoquera un comportement fluide sur le scroll:
<div onClick={() => {
ReactDOM.findDOMNode(this.headerRef)
.scrollIntoView({behavior: "smooth"});
}}
className='go-up-button' >
</div>
Vous pouvez transmettre d'autres paramètres à l'intérieur de scrollIntoView () La 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: Documents MDN
Toutes les solutions parlent d'ajouter le parchemin sur componentDidMount
ou componentDidUpdate
mais avec le DOM.
J'ai fait tout ça et je n'ai pas travaillé.
Alors, j'ai trouvé une autre solution qui me convient parfaitement.
Ajoutée
componentDidUpdate() { window.scrollTo(0, 0) }
sur l'en-tête, cette mine est hors de l'élément<Switch></Switch>
. Juste gratuit dans l'application. Travaux.
J'ai aussi trouvé quelque chose de ScrollRestoration , mais je suis paresseux maintenant. Et pour l’instant, je garderai la méthode "DidUpdate".
J'espère que ça aide!
fais attention
Quelque chose comme ça a fonctionné pour moi sur un composant:
<div ref="scroller" style={{height: 500, overflowX: "hidden", overflowY: "auto"}}>
//Content Here
</div>
Ensuite, quelle que soit la fonction traitant des mises à jour:
this.refs.scroller.scrollTop=0