javascript React 中的 getSnapshotBeforeUpdate() 是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53193786/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:08:08  来源:igfitidea点击:

What is getSnapshotBeforeUpdate() in React?

javascriptreactjsreact-native

提问by Hemadri Dasari

I went through below React official site to understand about new life cycle method getSnapshotBeforeUpdate

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

But I couldn't understand the advantage of this method and when exactly we should use.

但我无法理解这种方法的优势以及我们应该在什么时候使用。

Below is the example from docs and it differentiates two methods.

下面是来自文档的示例,它区分了两种方法。

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

回答by Marcell Toth

The main difference is getSnapshotBeforeUpdateruns beforethe update, componentDidUpdateruns after.

主要的区别是getSnapshotBeforeUpdate运行的更新,componentDidUpdate运行

So if there is anything you need to save before it gets overwritten, that's what getSnapshotBeforeUpdateis for. These are usually externally managed things (uncontrolledin React terms), such as the scrollPosition in your example, or when interoping with other libraries outside React (e.g. a jQuery plugin).

因此,如果您需要在被覆盖之前保存任何内容,这就是getSnapshotBeforeUpdate目的。这些通常是外部管理的东西(在 React 术语中不受控制),例如示例中的 scrollPosition,或者与 React 之外的其他库(例如 jQuery 插件)互操作时。

The main guideline is that if you are unsure, you probably don't need it. If you do, you will know it.

主要指导原则是,如果您不确定,您可能不需要它。如果你这样做了,你就会知道。

回答by Johannes Reuter

The two paragraphs above the example you quoted explain the need for that:

您引用的示例上方的两段解释了这样做的必要性:

In the above example, componentWillUpdate is used to read the DOM property. However with async rendering, there may be delays between “render” phase lifecycles (like componentWillUpdate and render) and “commit” phase lifecycles (like componentDidUpdate). If the user does something like resize the window during this time, the scrollHeight value read from componentWillUpdate will be stale.

The solution to this problem is to use the new “commit” phase lifecycle, getSnapshotBeforeUpdate. This method gets called immediately before mutations are made (e.g. before the DOM is updated). It can return a value for React to pass as a parameter to componentDidUpdate, which gets called immediately after mutations.

在上面的例子中,componentWillUpdate 用于读取 DOM 属性。然而,对于异步渲染,“渲染”阶段生命周期(如 componentWillUpdate 和渲染)和“提交”阶段生命周期(如 componentDidUpdate)之间可能存在延迟。如果用户在此期间执行诸如调整窗口大小之类的操作,则从 componentWillUpdate 读取的 scrollHeight 值将过时。

这个问题的解决方案是使用新的“提交”阶段生命周期,getSnapshotBeforeUpdate。这个方法会在发生变化之前立即调用(例如在 DOM 更新之前)。它可以为 React 返回一个值作为参数传递给 componentDidUpdate,它在发生变化后立即被调用。

In other words: React 16.6 introduced a new feature called "Suspense". This feature enables async rendering - the rendering of a subtree of react components can be delayed (for example to wait for a network resource to load). It is also used internally by React to favor important DOM updates over othersto increase the perceived rendering performance. This can - as one would expect - cause substantial delays between the react-side virtual DOM rendering (which triggers componentWillUpdateand render(), but may contain some async component subtree which has to be awaited) and the actual reflection to the DOM (which triggers componentDidUpdate). In older react versions before Suspense these lifecycle hooks were always called with very little delay because the rendering was completely synchronous, which justified the pattern to gather DOM information in componentWillUpdateand use it in componentDidUpdate, which is no longer the case.

换句话说:React 16.6 引入了一个名为“Suspense”的新功能。此功能启用异步渲染 - React 组件子树的渲染可以延迟(例如等待网络资源加载)。React 也在内部使用它来支持重要的 DOM 更新而不是其他更新,以提高感知的渲染性能。正如人们所预料的那样,这可能会导致反应端虚拟 DOM 渲染(触发componentWillUpdaterender(),但可能包含一些必须等待的异步组件子树)和对 DOM 的实际反射(触发componentDidUpdate)。在 Suspense 之前的旧版 React 中,这些生命周期钩子总是以很小的延迟被调用,因为渲染是完全同步的,这证明了在 中收集 DOM 信息componentWillUpdate并在 中使用它的模式是合理的componentDidUpdate,现在不再是这种情况。