React,使用Refs来scrollIntoView()在componentDidUpdate()

时间:2017-07-13 09:45:02

标签: javascript reactjs react-redux

我在我的应用程序中使用Redux,在组件内部我希望在商店发生更改时滚动到特定的div标签。 我有Redux部分工作,所以它触发componentDidUpdate()方法(我已经路由到这个compoennt视图)。 据我所知,问题是scrollIntoView()方法没有正常工作cos componentDidUpdate()有一个默认行为,滚动到顶部覆盖scrollIntoView()。 为了解决这个问题,我在setTimeout中包含了调用scrollIntoView()的函数,以确保不会发生这种情况。 我想做的是调用一个preventDefault()或任何其他更优雅的解决方案,但我无法找到触发“滚动顶部”的事件的位置。 我在这里查看了文档:https://facebook.github.io/react/docs/react-component.html#componentdidupdate 并且在此函数中传递的参数是componentDidUpdate(prevProps,prevState),因为没有事件我不知道如何调用preventDefault()

我已关注此文档:https://facebook.github.io/react/docs/refs-and-the-dom.html 并尝试了人们在此建议的不同方法:How can I scroll a div to be visible in ReactJS?

没有任何效果 这是我的代码,如果有人对我有任何提示,谢谢

class PhotoContainer extends React.Component {

  componentDidUpdate(){
    setTimeout(() => {
     this.focusDiv();
    }, 500);

  }
  focusDiv(){
    var scrolling = this.theDiv;
    scrolling.scrollIntoView();

  }

  render() {
    const totalList = [];
    for(let i = 0; i < 300; i += 1) {
        totalList.push(
            <div key={i}>{`hello ${i}`}</div>
        );
    }

  return (
      <div >
          {totalList}
          <div ref={(el) => this.theDiv = el}>this is the div I'm trying to scroll to</div>
      </div>
  )

};     }

2 个答案:

答案 0 :(得分:1)

好的,已经有一段时间了,但是我让它在没有setTimeOut函数的其他项目中工作,所以我想回答这个问题。 由于Redux通过道具传递了新的更新,因此我使用了componentWillRecieveProps()方法而不是componentDidUpdate(),这使您可以更好地控制更新后的属性,并可以与scrollIntoView()函数一起使用。 / p>

class PhotoContainer extends React.Component {

  componentWillReceiveProps(newProps) {
    if (
      this.props.navigation.sectionSelected !==
        newProps.navigation.sectionSelected &&
      newProps.navigation.sectionSelected !== ""
    ) {
      this.focusDiv(newProps.navigation.sectionSelected);
    }
  }

  focusDiv(section){
    var scrolling = this[section]; //section would be 'theDiv' in this example
    scrolling.scrollIntoView({ blok: "start", behavior: "smooth" });
  }

  render() {
    const totalList = [];
    for(let i = 0; i < 300; i += 1) {
        totalList.push(
            <div key={i}>{`hello ${i}`}</div>
        );
    }

    return (
      <div >
          {totalList}
          <div ref={(el) => this.theDiv = el}>
            this is the div I am trying to scroll to
          </div>
       </div>
         )
      };
    }

答案 1 :(得分:0)

在响应 redux 存储更改的 React 中,我也很难滚动到列表的底部,我偶然发现了这一点以及其他一些与滚动相关的 stackoverflow 文章。如果您也遇到了这个问题,有几种方法可能会成为问题。我的情况是我想要一个“加载”微调屏幕,而列表正在渲染。以下是一些错误的方法:

  1. 当 loading = true 时,渲染微调器,否则渲染列表。
{loading ? 
   <Spinner />
:
   <List />
}

如上所述,这不起作用,因为您可能想要滚动到底部的列表尚未呈现。

  1. 加载时,将微调器的显示设置为阻止,列表中的设置为无。加载完成后,反转显示。
<div style={{display: loading ? 'block' : 'none'>
   <Spinner />
</div>
<div style={{display: loading ? 'none' : 'block'>
   <List />
</div>

这也不起作用,因为当您调用滚动时,您想要滚动到底部的列表实际上可能不会显示。

对于上述场景,更好的方法是使用加载作为组件的覆盖层。通过这种方式渲染和显示微调器和列表,滚动发生,加载完成后,微调器可以取消渲染或设置为不可见。