Подтвердить что ты не робот

Выделите в верхней части страницы после рендера в response.js

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

Проблема заключается в следующем: как прокручивается верхняя после визуализация новой коллекции?

'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;
4b9b3361

Ответ 1

Так как оригинальное решение было предоставлено для очень ранней версии реакции, вот обновление:

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

Ответ 2

Наконец, я использовал:

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

Ответ 3

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

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

Обновление 5/11/2019 для 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)
    }
  }

Ответ 4

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

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

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

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

Обратитесь: отреагируйте тренировки

Ответ 5

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

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

Пример кода:

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

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

Ответ 6

Вы можете сделать это в маршрутизаторе следующим образом:

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)} ставит верхнюю часть прокрутки. Для получения дополнительной информации проверьте: ссылка codepen

Ответ 7

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

В приведенном ниже примере компонент Blog оборачивается функцией ScrollIntoView(), поэтому, если маршрут изменяется при монтировании компонента Blog, то HOC ComponentDidUpdate обновит позицию прокрутки окна.

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

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

Приведенный выше пример прекрасно работает, но если вы перешли на react-router-dom, то вы можете упростить вышеперечисленное, создав HOC который оборачивает компонент.

Еще раз, вы также можете так же легко обернуть его на маршрутах (просто изменить componentDidMount метод к componentDidUpdate метод примера кода, написанного выше, а также упаковка ScrollIntoView с withRouter).

контейнеры/ScrollIntoView.js

import { PureComponent, Fragment } from "react";

class ScrollIntoView extends PureComponent {
  componentDidMount = () => window.scrollTo(0, 0);

  render = () => this.props.children
}

export default ScrollIntoView;

компоненты/Home.js

import React from "react";
import ScrollIntoView from "../containers/ScrollIntoView";

export default () => (
  <ScrollIntoView>
    <div className="container">
      <p>
        Sample Text
      </p>
    </div>
  </ScrollIntoView>
);

Ответ 8

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

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

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

Пример кода -

Шаг 1 - создайте компонент 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)

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

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

Ответ 9

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

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

Ответ 10

Для тех, кто использует хуки, будет работать следующий код.

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

Обратите внимание, что вы также можете напрямую импортировать useEffect: import { useEffect } from 'react'

Ответ 11

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

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

Ответ 12

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

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

Измените CSS для высоты/минимальной высоты: 100% на высоту/минимальной высоты: 100vh.

Документы для разработчиков Google

Ответ 13

Все вышесказанное не помогло мне - не знаю почему, но:

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

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

Ответ 14

Ни один из приведенных выше ответов в настоящее время не работает для меня. Оказывается, что .scrollTo не так широко совместим, как .scrollIntoView.

В нашем App.js, в componentWillMount() мы добавили

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

Это единственное решение, которое работает для нас повсеместно. root - это идентификатор нашего приложения. "Плавное" поведение не работает на каждом браузере/устройстве. Тайм-аут 777 немного консервативен, но мы загружаем много данных на каждую страницу, поэтому через тестирование это было необходимо. Короче 237 может работать для большинства приложений.

Ответ 15

Я использую React Hooks и хотел что-то повторно используемое, но также и то, что я мог бы вызвать в любое время (а не только после рендеринга).

// utils.js
export const useScrollToTop = (initialScrollState = false) => {
  const [scrollToTop, setScrollToTop] = useState(initialScrollState);

  useEffect(() => {
    if (scrollToTop) {
      setScrollToTop(false);
      try {
        window.scroll({
          top: 0,
          left: 0,
          behavior: 'smooth',
        });
      } catch (error) {
        window.scrollTo(0, 0);
      }
    }
  }, [scrollToTop, setScrollToTop]);

  return setScrollToTop;
};

Затем, чтобы использовать крючок, вы можете сделать:

import { useScrollToTop } from 'utils';

const MyPage = (props) => {
  // initialise useScrollToTop with true in order to scroll on page load 
  const setScrollToTop = useScrollToTop(true);

  ...

  return <div onClick={() => setScrollToTop(true)}>click me to scroll to top</div>
}

Ответ 16

Этот код будет вызывать плавное поведение прокрутки:

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

Более подробную информацию можно найти здесь: MDN документы

Ответ 17

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

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

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

this.refs.scroller.scrollTop=0

Ответ 18

Все решения говорят о добавлении прокрутки на componentDidMount или componentDidUpdate но с DOM.

Я сделал все это и не работал.

Итак, выяснил какой-то другой способ, который отлично подходит для меня.

Добавлен componentDidUpdate() { window.scrollTo(0, 0) } в заголовке, что моя из-за элемента <Switch></Switch>. Просто бесплатно в приложении. Работает.

Я также нашел кое-что о ScrollRestoration, но теперь я ленив. И на данный момент держим это "DidUpdate".

Надеюсь, поможет!

быть в безопасности

Ответ 19

Ни один из приведенных выше ответов в настоящее время не работает для меня. Оказывается, что .scrollTo не так широко совместим, как .scrollIntoView.

В нашем App.js, в componentWillMount() мы добавили

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

Это единственное решение, которое работает для нас повсеместно. root - это идентификатор нашего приложения. "Плавное" поведение не работает на каждом браузере/устройстве. Тайм-аут 777 немного консервативен, но мы загружаем много данных на каждую страницу, поэтому через тестирование это было необходимо. Короче 237 может работать для большинства приложений.

Ответ 20

Крюковое решение:

  • Создать хук ScrollToTop

    import { useEffect } from "react";
    import { withRouter } from "react-router-dom";

    const ScrollToTop = ({ children, location: { pathname } }) => {
      useEffect(() => {
        window.scrollTo({
          top: 0,
          left: 0,
          behavior: "smooth"
        });
      }, [pathname]);

      return children || null;
    };

    export default withRouter(ScrollToTop);

  • Оберните свое приложение этим

    <Router>
        <ScrollToTop>
           <App />
        </ScrollToTop>
    </Router>

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