在react.js中渲染后滚动到页面顶部

And*_*nko 135 scroll render reactjs

我有一个问题,我没有想法,如何解决.在我的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;
Run Code Online (Sandbox Code Playgroud)

rac*_*mic 236

最后..我用过:

componentDidMount() {
  window.scrollTo(0, 0)
}
Run Code Online (Sandbox Code Playgroud)

  • 这不知何故对我不起作用. (11认同)
  • 对于那些使用钩子的人来说,以下代码将起作用。`React.useEffect(() =&gt; { window.scrollTo(0, 0); }, []);` 注意,你也可以直接导入 useEffect: `import { useEffect } from 'react'` (7认同)
  • 这只是对我有用的解决方案.还尝试了:ReactDOM.findDOMNode(this).scrollTop = 0和componentDidMount(){this._div.scrollTop = 0} render(){return <div ref = {(ref)=> this._div = ref} />} (2认同)
  • @Tomasz - 我发现有时当我将某些div设置为高度或最小高度时,我仍然遇到这个问题:100%.我不得不删除并将其包装在父级中,或者进一步移动到仍然可以滚动的树中 (2认同)
  • 这对我有用,但不适用于componentDidMount,因为当状态更改导致重新呈现页面时,可能不会触发CDM.所以把这个调用 - window.scrollTo(0,0); - 无论你在哪里改变状态. (2认同)

And*_*nko 57

由于原始解决方案是针对反应的早期版本提供的,因此这是一个更新:

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
Run Code Online (Sandbox Code Playgroud)

  • `这是箭头函数中未定义的'是不正确的.this关键字绑定到与封闭函数相同的上下文https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions (12认同)

J. *_*ens 42

你可以使用这样的东西.ReactDom用于反应.14.只是反应.

    componentDidUpdate = () => { ReactDom.findDOMNode(this).scrollIntoView(); }
Run Code Online (Sandbox Code Playgroud)


Vis*_*tty 17

在React Routing中,存在如下问题:如果我们重定向到新路由,则它不会自动将您带到页面顶部.

即使我确实有同样的问题.

我刚刚将单行添加到我的组件中,它就像黄油一样.

componentDidMount() {
    window.scrollTo(0, 0);
}
Run Code Online (Sandbox Code Playgroud)

参考:反应训练


Pow*_*ham 15

对于那些使用钩子的人,以下代码将起作用。

React.useEffect(() => {
  window.scrollTo(0, 0);
}, []);
Run Code Online (Sandbox Code Playgroud)

注意,您也可以直接导入 useEffect: import { useEffect } from 'react'

  • “[]”作为第二个参数意味着它只会在第一次渲染时发生,你尝试过不使用吗? (2认同)

GGA*_*hee 13

这可能,也可能应该使用refs来处理:

"...你可以使用ReactDOM.findDOMNode作为"逃生舱"但我们不推荐它,因为它打破了封装,几乎在所有情况下都有更清晰的方法在React模型中构建你的代码.

示例代码:

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

    render() {
        return <div ref={(ref) => this._div = ref} />
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 使用字符串的@chuckfactory设置引用可能会在某个时候被删除,并且实际上存在一些您可能想了解的有趣的缺点。https://news.ycombinator.com/edit?id=12093234 (2认同)

Que*_*n C 12

挂钩解决方案

  • 创建一个 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);

Run Code Online (Sandbox Code Playgroud)
  • 用它包装你的应用程序

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

Run Code Online (Sandbox Code Playgroud)

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


Aka*_*eth 12

我已经尝试过 @sledgeweight 解决方案,但它对于某些视图效果不佳。但添加 setTimeout 似乎效果很好。万一有人遇到和我一样的问题。下面是我的代码。

import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'

const ScrollToTop = () => {
    const { pathname } = useLocation()
    useEffect(() => {
        console.log(pathname)
        /* settimeout make sure this run after components have rendered. This will help fixing bug for some views where scroll to top not working perfectly */
        setTimeout(() => {
            window.scrollTo({ top: 0, behavior: 'smooth' })
        }, 0)
    }, [pathname])
    return null
}

export default ScrollToTop
Run Code Online (Sandbox Code Playgroud)

在 AppRouter.js 中将其用作

<Router>
    <ScrollToTop/>
    <App>
</Router>
Run Code Online (Sandbox Code Playgroud)


bel*_*lle 10

这对我有用。

import React, { useEffect } from 'react';

useEffect(() => {
    const body = document.querySelector('#root');

    body.scrollIntoView({
        behavior: 'smooth'
    }, 500)

}, []);
Run Code Online (Sandbox Code Playgroud)


Roh*_*had 10

该解决方案适用于功能组件和类基。

首先,我不喜欢每次重新渲染时滚动到顶部的想法,相反,我喜欢特定事件的附加功能。

步骤#1:创建一个 ScrollToTop 函数

const scrollToTop = () => {
    window.scrollTo({
        top: 0,
        behavior: "smooth",
    });
};
Run Code Online (Sandbox Code Playgroud)

event步骤#2:在eg上调用这个函数onClick

onRowClick={scrollToTop()}
// onClick={scrollToTop()}
// etc...
Run Code Online (Sandbox Code Playgroud)


Ana*_*era 9

您可以在路由器中执行此操作:

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'));
Run Code Online (Sandbox Code Playgroud)

onUpdate={() => window.scrollTo(0, 0)}把滚动顶部.有关更多信息,请检查:codepen链接


小智 8

点击后出现的页面,写入即可。

  componentDidMount() {
    window.scrollTo(0, 0);
  } 
Run Code Online (Sandbox Code Playgroud)


小智 8

我在 React 17.0 中使用功能组件和 window.scroll、window.scrollTo 进行 SPA,所有这些变体对我来说都不起作用。所以我使用 useRef 钩子做了一个解决方案。我使用 Ref 在组件顶部创建了一个 span 标签,然后使用 ref.current.scrollIntoView() 进行效果

有一个简短的例子:

import React, { useEffect,useRef} from 'react';

export const ExampleComponent = () => {

  const ref = useRef();

  useEffect(() => {
      ref.current.scrollIntoView()
  }, []);

return(

 <>
   <span ref={ref}></span>
   <YourCodeHere />
   <MoreCode />
</>
Run Code Online (Sandbox Code Playgroud)

) }


小智 8

平滑滚动到顶部。在钩子中,您可以在生命周期安装状态中使用此方法进行一次渲染

useEffect(() => {
  window.scrollTo({top: 0, left: 0, behavior: 'smooth' });
}, [])
Run Code Online (Sandbox Code Playgroud)


Mat*_*tta 7

这是另一种方法,允许您选择希望窗口滚动位置重置为哪个已安装的组件,而不会大量复制ComponentDidUpdate/ComponentDidMount.

下面的示例是使用ScrollIntoView()包装Blog组件,因此如果在安装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);
}
Run Code Online (Sandbox Code Playgroud)

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>
);
Run Code Online (Sandbox Code Playgroud)

上面的示例效果很好,但如果您已迁移到react-router-dom,则可以通过创建包装组件的渲染道具来简化上述操作.

再次,你也可以很容易地把它包在你的路线(只是改变HOC方法,将componentDidMount上面写的方法示例代码,以及包装componentDidUpdateScrollIntoView).

工作示例:https://codesandbox.io/s/qq4x5x43k9(仅点击主页更新窗口位置)

集装箱/ ScrollIntoView.js

import { PureComponent, Fragment } from "react";

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

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

export default ScrollIntoView;
Run Code Online (Sandbox Code Playgroud)

组件/ Home.js

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

export default () => (
  <ScrollIntoView>
    <div className="container">
      <p>
        Sample Text
      </p>
    </div>
  </ScrollIntoView>
);
Run Code Online (Sandbox Code Playgroud)


小智 6

这是唯一对我有用的东西(带有ES6类组件):

componentDidMount() {
  ReactDOM.findDOMNode(this).scrollIntoView();
}
Run Code Online (Sandbox Code Playgroud)


Arp*_*pit 6

我正在使用react-router ScrollToTop组件,其代码在react-router docs中描述

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

我正在更改单个Routes文件中的代码,之后不需要在每个组件中更改代码.

示例代码 -

第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)
Run Code Online (Sandbox Code Playgroud)

步骤2 - 在App.js文件中,添加ScrollToTop Component <Router

const App = () => (
  <Router>
    <ScrollToTop>
      <App/>
    </ScrollToTop>
  </Router>
)
Run Code Online (Sandbox Code Playgroud)


小智 6

以上所有对我都不起作用 - 不知道为什么,但是:

componentDidMount(){
    document.getElementById('HEADER').scrollIntoView();
}
Run Code Online (Sandbox Code Playgroud)

工作,其中 HEADER 是我的标题元素的 id


Shu*_*rda 6

对于 React v18+,我的建议是使用包装组件,这是最简单的执行方法。

第1步:创建ScrollToTop组件(component/ScrollToTop.js)

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

export function ScrollToTop() {
  const { pathname } = useLocation();

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

  return null;
}
Run Code Online (Sandbox Code Playgroud)

第 2 步:用它包装您的应用程序 (index.js)

<React.StrictMode>
  <BrowserRouter>
    <ScrollToTop />
    <App />
  </BrowserRouter>
</React.StrictMode>
Run Code Online (Sandbox Code Playgroud)

说明:每次路径名更改时,都会调用 useEffect 将页面滚动到顶部。


小智 5

在功能组件中使用 Hooks,假设在结果 props 中有更新时组件更新

import React, { useEffect } from 'react';

export const scrollTop = ({result}) => {
  useEffect(() => {
    window.scrollTo(0, 0);
  }, [result])
}
Run Code Online (Sandbox Code Playgroud)


jer*_*naa 5

如果所有想做的事情都很简单,这里有一个适合所有人的解决方案

添加这个小功能

scrollTop()
{
    window.scrollTo({
        top: 0,
        behavior: "smooth"
    });
}
Run Code Online (Sandbox Code Playgroud)

从页面的页脚调用函数如下

<a className="scroll-to-top rounded" style={{display: "inline"}} onClick={this.scrollTop}>TOP</a>
Run Code Online (Sandbox Code Playgroud)

如果你想在这里添加漂亮的样式是 css

scrollTop()
{
    window.scrollTo({
        top: 0,
        behavior: "smooth"
    });
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我尝试了一切,但这是唯一有效的。

 useLayoutEffect(() => {
  document.getElementById("someID").scrollTo(0, 0);
 });
Run Code Online (Sandbox Code Playgroud)


And*_*ndy 5

看起来所有 useEffect 示例都没有考虑到您可能希望通过状态更改来触发此操作。

const [aStateVariable, setAStateVariable] = useState(false);

const handleClick = () => {
   setAStateVariable(true);
}

useEffect(() => {
  if(aStateVariable === true) {
    window.scrollTo(0, 0)
  }
}, [aStateVariable])
Run Code Online (Sandbox Code Playgroud)