代码之家  ›  专栏  ›  技术社区  ›  Hemadri Dasari

React中的getSnapshotBeforeUpdate()是什么?

  •  2
  • Hemadri Dasari  · 技术社区  · 7 年前

    我通过下面的官方网站了解了新的生命周期方法 getSnapshotBeforeUpdate

    但是我不明白这种方法的优点以及我们应该在什么时候使用。

    getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
    }
    
    componentDidUpdate(prevProps, prevState, snapshot) {
        // If we have a snapshot value, we've just added new items.
       // Adjust scroll so these new items don't push the old ones out of view.
       // (snapshot here is the value returned from getSnapshotBeforeUpdate)
       if (snapshot !== null) {
          const list = this.listRef.current;
           list.scrollTop = list.scrollHeight - snapshot;
        }
      }
    
    2 回复  |  直到 7 年前
        1
  •  21
  •   Johannes Reuter    7 年前

    你引用的例子上面的两段解释了这一点的必要性:

    在上面的示例中,componentWillUpdate用于读取DOM 渲染阶段生命周期(如componentWillUpdate和render)和 提交阶段生命周期(如componentDidUpdate)。如果用户 类似于在这段时间调整窗口大小,滚动高度

    生命周期,更新前获取快照。调用此方法 在突变发生之前(例如,在DOM发生之前 已更新)。它可以将React to pass的值作为参数返回给 componentDidUpdate,在突变后立即调用。

    换句话说:React 16.6引入了一个新特性 "Suspense" . 此功能支持异步呈现-可以延迟react组件子树的呈现(例如等待网络资源加载)。它也被React to内部使用 favor important DOM updates over others 以提高可感知的渲染性能。正如人们所料,这会导致react端虚拟DOM呈现(触发 componentWillUpdate 和 render() ,但可能包含一些必须等待的异步组件子树)和对DOM的实际反射(触发 componentDidUpdate 组件将更新 组件更新 ,情况不再如此。

        2
  •  22
  •   Marcell Toth    7 年前

    getSnapshotBeforeUpdate 跑 之前 componentDidUpdate 跑 .

    更新前获取快照 是给你的。这些通常是外部管理的东西( 不受控制 在React术语中),例如示例中的scrollPosition,或者在与React外部的其他库(例如jQuery插件)交互时。

    你可能不需要它

        4
  •  1
  •   Chong Lip Phang    5 年前

    实际上,getSnapshotBeforeUpdate()运行 之后

    class Demo extends React.Component {
        constructor(props) {
          super(props);
          this.state = {x:1};
          console.log(1);
       }
       componentDidMount() {
          this.setState({x:2});
          console.log(3);
       }
       shouldComponentUpdate() {
          console.log(4);
          return true;
       }
       getSnapshotBeforeUpdate(prevProps, prevState){
          console.log(5,prevState.x,this.state.x);
          return 999;
       }
       componentDidUpdate(prevProps, prevState, snapshot) {
          console.log(6,snapshot);
       }
       componentWillUnmount() {
          console.log(7);
       }
       render() {
          console.log(2);
          return null;
       }
    }
    
    ReactDOM.render(
       <Demo />,
       document.querySelector('div')
    );
    ReactDOM.unmountComponentAtNode(document.querySelector('div'));
    

    输出为:

    1
    2
    3
    4
    2
    5 1 2
    6 999
    7