【问题标题】:How to scroll to bottom when props changed in react-virtualized?react-virtualized中道具更改时如何滚动到底部?
【发布时间】:2019-01-17 02:04:39
【问题描述】:

我有来自 react-virtualized 库的组件应用程序列表。 而且我需要在初始渲染时,让我的列表滚动到底部。

当我添加了 scrollToIndex 选项时,我做到了。但是当我在列表数组中添加新对象时,它不会滚动到我最后添加的对象。我该如何解决?使用“forceUpdate()”函数是不是很好的解决方案?

import { List } from "react-virtualized";
import loremIpsum from 'lorem-ipsum';

const rowCount = 1000;
const listHeight = 600;
const rowHeight = 50;
const rowWidth = 800;

class App extends Component {
  constructor() {
    super();
    this.renderRow = this.renderRow.bind(this);
    this.list = Array(rowCount).fill().map((val, idx) => {
      return {
        id: idx, 
        name: 'John Doe',
        image: 'http://via.placeholder.com/40',
        text: loremIpsum({
          count: 1, 
          units: 'sentences',
          sentenceLowerBound: 4,
          sentenceUpperBound: 8 
        })
      }
    });
  }

  handle = () => {
    this.list = [...this.list, { id: 1001, name: "haha", image: '', text: 'hahahahahaha' }];
    this.forceUpdate();
    this.refs.List.scrollToRow(this.list.length);
  };


  renderRow({ index, key, style }) {
    console.log('____________', this.list.length);

    return (
      <div key={key} style={style} className="row" >
        <div className="image">
          <img src={this.list[index].image} alt="" />
        </div>
        <div onClick={this.handle}>{this.state.a}</div>
        <div className="content">
          <div>{this.list[index].name}</div>
          <div>{this.list[index].text}</div>
        </div>
      </div>
    );
  }

  render() {
    return (
      <div className="App">
        <div className="list">
          <List
            ref='List'
            width={rowWidth}
            height={listHeight}
            rowHeight={rowHeight}
            rowRenderer={this.renderRow}
            rowCount={this.list.length}
            overscanRowCount={3}
            scrollToIndex={this.list.length}
            />
        </div>
      </div>
    );
  }
}

export default App;

【问题讨论】:

    标签: reactjs react-virtualized


    【解决方案1】:

    您提到更改列表项时需要滚动到底部,老实说我不喜欢使用forceUpdate。如 React 文档所述:

    通常你应该尽量避免使用 forceUpdate() 并且只在 render() 中读取 this.props 和 this.state。

    幸运的是,React 生命周期方法之一适合这种情况,它是调用componentDidUpdate。但是您需要对代码进行一些重构。而不是使用私有字段,我建议将它放在状态/道具上。

    该方法将在更新 props/state 发生后立即调用。但是,初始渲染不会调用此方法。

    你需要做的是,比较道具,有没有变化?然后拨打this.refs.List.scrollToRow(this.list.length);

    示例代码

    class App extends Component {
      constructor() {
        this.state = {
          list: [] // put your list data here
        }
      }
    
      // Check the change of the list, and trigger the scroll
      componentDidUpdate(prevProps, prevState) {
        const { list } = this.state;
        const { list: prevList } = prevState;
        if (list.length !== prevList.length) {
          this.refs.List.scrollToRow(list.length);  
        }
      }
    
      render() {
        // usual business
      }
    }

    更多关于 React 生命周期方法的参考:

    https://reactjs.org/docs/react-component.html#componentdidupdate

    【讨论】:

    • 感谢您的回答。例如,如果列表来自减速器状态,它会起作用吗?从 componentDidMount 上的数据库加载客户端上的所有庞大对象数组是个好主意吗?还是在滚动上上传部分(在服务器上发送请求)更好的主意?
    • 是的,如果来自reducer状态,这是最好的组合,更容易调试。如果您在componentDidMount 上加载巨大的数组,则主要问题会导致 js 线程被阻塞并且一些动画或交互被阻塞。最好按照您的建议进行分页,并在到达底部时加载更多项目。
    • 当道具改变和/或列表项改变时,如果我们想滚动到顶部(第一行)应该怎么做? ScrollToRow 允许我们滚动更多,但如果我们想向后滚动呢?
    猜你喜欢
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 2011-07-05
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2015-07-01
    相关资源
    最近更新 更多