说明:获取之前的状态

Explanation: Get previous state

我正在阅读 React 文档,有一个主题我不是很了解:

https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state

function Counter() {
  const [count, setCount] = useState(0);

  const prevCountRef = useRef();
  useEffect(() => {
    prevCountRef.current = count;
  });
  const prevCount = prevCountRef.current;

  return <h1>Now: {count}, before: {prevCount}</h1>;
}

演示:

https://codesandbox.io/s/get-previous-state-ref--hook-faq-w0f3k?file=/src/App.js

我想要对此有更好的解释。亲,效果如何?谢谢

您可以使用 componentDidUpdate 获取上一个道具和状态。当您扩展 React.Component 时,它会在每次渲染后调用 componentDidUpdate。您定义函数,React 会将 prev props 和 prev state 传递给您。

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

这里有三件作品。一个 state、一个 ref 和一个 effect.

状态是在渲染之间记住的值,并且在更改时重新渲染它的组件。

引用(或ref)是一个像状态一样在渲染之间持续存在的值,但与状态不同的是,它不会监视任何更改并且可以自由变异。对 refs 的更改永远不会导致渲染。

效果只是一个函数,它在渲染之后运行,或者在其依赖项之一的渲染自上次渲染后发生更改之后运行。


所以把这些放在一起会发生什么:

const [count, setCount] = useState(0);

这里声明了一个状态。使用新值调用 setCount 将导致组件呈现,当呈现时,count 将具有设置的值。

const prevCountRef = useRef();

然后声明ref。这将保存对先前计数值的 reference。现在它没有值(undefined),考虑到组件首次呈现时没有先前的值,这是有道理的。

useEffect(() => {
  prevCountRef.current = count;
});

现在声明一个 effect 运行 after 每次渲染(你可以这么说是因为它没有依赖关系(将是第二个参数到 useEffect())。当它运行时,它将 prevCountRef 的当前值设置为任何计数。


因此,在第一次渲染时,在伪代码中:

// render starts

count // 0
prevCountRef.current // undefined

// render finishes

effect runs {
  prevCountRef.current is set to 0
}

因此,当渲染发生时,count 状态为 0 并且先前的计数参考为 undefined


第二次渲染:

setCount(1) // triggers the second render

// second render starts

count // 1
prevCount.current // 0

// second render finishes

effect runs {
  prevCount.current is set to 1  
}

正如您所见,在渲染过程中,您始终将当前计数作为状态,将之前的计数作为参考。这是有效的,因为设置 refs 值的效果总是在渲染完成后运行,这允许它是以前的值。

useEffect 在组件渲染后调用。 组件第一次渲染prevCount是undefined因为useEffect还没有被调用

预渲染: 1) value: 0, prevCount: undefined

post-渲染: useEffect 被调用:

2) value: 0, prevCount: 0 useRef 不会引起新的渲染,因此组件不会更新。 refCount 将显示为未定义。

当您更改计数值时,组件会重新呈现:

预渲染:

3) value: 1, prevCount: 0 useEffect 尚未调用。

post-渲染:

4) value: 1, prevCount: 1 useEffect 被调用,prevCount 增加但组件没有更新所以 prevCount 将显示为 value = 0;