【问题标题】:React, Using Refs to scrollIntoView() doen't work on componentDidUpdate()React,使用 Refs 来 scrollIntoView() 对 componentDidUpdate() 不起作用
【发布时间】:2017-12-18 00:32:08
【问题描述】:

我在我的应用程序中使用 Redux,在我想在商店发生更改时滚动到特定 div 标签的组件内。 我有 Redux 部分工作,所以它触发 componentDidUpdate() 方法(我已经路由到这个组件视图)。 据我所知,问题在于方法 scrollIntoView() 无法正常工作,因为 componentDidUpdate() 具有滚动到顶部的默认行为,会覆盖 scrollIntoView()。 为了解决这个问题,我将调用 scrollIntoView() 的函数包装在 setTimeout 中,以确保以后发生。 我想做的是调用 preventDefault() 或任何其他更优雅的解决方案,但我找不到触发“scrollTop”的事件的位置 我在这里查看了文档: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>
  )

}; }

【问题讨论】:

  • 您确定您使用的浏览器版本支持 scrollIntoView 吗? developer.mozilla.org/en/docs/Web/API/Element/…
  • 另外,检查 'input' 在你的 ref 回调中是否真实可能会有所帮助,记住 ref 是在 mount 时使用元素调用,在 unmount 时使用 null (facebook.github.io/react/docs/refs-and-the-dom.html)
  • 是的,我使用的是 Chrome 版本 59.0.3071.115(官方版本)(64 位),上面写着 29,我猜如果它比它支持的更大。起初我很想使用 element.scrollIntoView({block: "start", behavior: "smooth"}) 但阅读浏览器支持的参数并不多,所以我坚持使用基本支持。我还尝试了布尔参数(真假)以防万一,但没有帮助感谢@Finbarr O'B的提示
  • 最简单的真实检查是做if(input){ this.textInput = input; },但我怀疑这不是你的问题。我刚刚尝试运行您的代码,它似乎适用于我的情况。我必须包含 componentDidMount() 但是因为我没有在组件中的任何地方操作状态(仅在组件状态发生更改时才调用 componentDidUpdate() )。我还删除了引导 CSS 类。见这里:github.com/finbarrobrien/reacty/blob/master/src/App.js
  • 我刚刚克隆了你的 github 'reacty' 并且在我这边也可以正常工作,我只是尝试像你一样删除引导 CSS 类但仍然无法正常工作,现在我知道它适用于这个更简单的版本,我将努力简化代码以使其工作并从那里开始,谢谢,我会及时通知您

标签: javascript reactjs react-redux


【解决方案1】:

好的,已经有一段时间了,但我让它在另一个没有setTimeOut 功能的项目中工作,所以我想回答这个问题。 由于 Redux 通过 props 传递新的更新,所以我使用了 componentWillRecieveProps() 方法而不是 componentDidUpdate() ,这可以让您更好地控制更新的属性,并且可以使用 scrollIntoView() 函数按预期工作。

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({ block: "start", behavior: "smooth" });//corrected typo
  }

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

【讨论】:

  • 我正在使用功能组件,所以不能使用 componentWillRecieveProps 所以我使用 setTimeOut 和 0。谢谢你的提示 :)
【解决方案2】:

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

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

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

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

这也不起作用,因为当您调用滚动条时,您想要滚动到底部的列表实际上并没有显示出来。

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

【讨论】:

    猜你喜欢
    • 2018-05-27
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-12
    • 2019-11-18
    • 1970-01-01
    相关资源
    最近更新 更多