Перейдите к верхней части страницы, после рендеринга в реакцию.js


У меня есть проблема, которой у меня нет идей, как ее решить. В моем компоненте react я показываю длинный список данных и несколько ссылок внизу. После нажатия на любую из этих ссылок я заполняю список новой коллекцией ссылок и должен прокрутить ее вверх.

проблема в том-как прокрутить до верха после новая коллекция рендеринга?

'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 67

14 ответов:

наконец-то.. Я использовал:

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

Я решил эту проблему, добавив:

componentDidUpdate() {
  ReactDOM.findDOMNode(this).scrollTop = 0
},

вы могли бы использовать что-то вроде этого. ReactDom - это для react.14. Просто реагируй иначе.

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

Это может и, вероятно, должно быть обработано с помощью refs:

"... вы можете использовать ReactDOM.findDOMNode как "аварийный люк", но мы не рекомендуем его, поскольку он нарушает инкапсуляцию, и почти в каждом случае есть более четкий способ структурировать ваш код в модели React."

пример кода:

class MyComponent extends React.Component {
    componentDidMount() {
        this._div.scrollTop = 0
    }

    render() {
        return <div ref={(ref) => this._div = ref} />
    }
}

Вы можете сделать это в роутере так:

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'));

The onUpdate={() => window.scrollTo(0, 0)} поместите верхнюю часть прокрутки. Для получения дополнительной информации проверьте: http://codepen.io/Yuschick/post/react-reset-scroll-position-when-changing-routes

вы можете просто использовать это:

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

Я использую компонент react-router ScrollToTop, код которого описан в документах react-router

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

Я меняю код в одном файле маршрутов, и после этого нет необходимости менять код в каждом компоненте.

Пример Кода

Шаг 1 - создать ScrollToTop.компонент Яш

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)

Шаг 2 - В Приложении.js-файл, добавить компонент ScrollToTop после <Router

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

вот еще один подход, который позволяет вам выбрать, какие смонтированные компоненты вы хотите, чтобы положение прокрутки окна было сброшено без массового дублирования ComponentDidUpdate / ComponentDidMount.

приведенный ниже пример обертывает компонент блога с помощью ScrollIntoView (), так что если маршрут изменяется при монтировании компонента блога, то компонент HOC's ComponentDidUpdate обновит положение прокрутки окна.

Вы можете так же легко обернуть его по всему приложение, так что при любом изменении маршрута, это вызовет сброс окна.

маршруты.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);
}

это единственное, что работало для меня (с компонентом класса ES6):

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

в React Routing есть проблема, что если мы перенаправим на новый маршрут, то он не будет автоматически доставлять вас в верхнюю часть страницы.

даже у меня была такая же проблема.

Я просто добавил одну строку к моему компоненту, и он работал как масло.

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

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

все вышеперечисленное не сработало для меня-не знаю почему, но:

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

работал, где заголовок-это идентификатор моего элемента заголовка

Если вы делаете это для мобильный по крайней мере с Chrome, вы увидите белую полосу внизу.

Это происходит, когда строка URL исчезает. Решение:

изменить css для высоты / мин-высота:100% на высоте/мин-высота: 100vh.

https://developers.google.com/web/updates/2016/12/url-bar-resizing

этот код вызовет ровное поведение на свиток:

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

вы можете передать другие параметры внутри scrollIntoView() Можно использовать следующий синтаксис:

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

alignToTop необязательный Является логическим значением:

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 необязательный Является объектом со следующими свойствами:

*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".

более подробную информацию можно найти здесь: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

что-то вроде этого работало для меня на компоненте:

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

затем в любой функции, имеющей дело с обновлениями:

this.refs.scroller.scrollTop=0