reactjs useRef存储先前状态值

wdebmtf2  于 2023-01-08  发布在  React
关注(0)|答案(3)|浏览(321)

我对下面使用useRef来存储先前状态值感到困惑。本质上,它如何能够正确显示先前的值。由于useEffect依赖于“value”,我的理解是每次“value”更改(即当用户更新文本框时),它都会将“prevValue.current”更新为新键入的值。
但这并不是看起来正在发生的事情,这种情况下的步骤顺序是什么?

function App() {
  const [value, setValue] =  useState("");
  const prevValue = useRef('')
  useEffect(() => {
    prevValue.current = value;
  }, [value]);
  return (
    <div>
      <input
        value={value}
        onChange={e => setValue(e.target.value)}
      />
      <div>
        Curr Value: {value}
      </div>
      <div>
        Prev Value: {prevValue.current}
      </div>
    </div>
  );
}
bvpmtnay

bvpmtnay1#

好吧,虽然这在技术上是可行的,但这是一种令人困惑的方式,当你添加更多的东西时可能会导致bug。它可行的原因是useEffect状态更改后运行,更改ref值不会导致重新渲染。一个更好的方法是在onChange处理程序中更新ref值。而不是在效果上。但是你发布的代码的工作方式如下:
1.最初,两者都为空
1.用户键入内容,通过setValue触发状态更改
1.这将触发重新呈现,因此{value}是新值,但由于ref尚未更新,因此{prevValue.current}仍然呈现为
1.接下来,在渲染之后,效果运行,因为它有value作为依赖项。
1.但是,由于更改ref值不会触发重新渲染,因此新值不会反映在渲染的内容中
所以一旦上面的步骤完成,那么从技术上讲state值和ref是相同的值,但是,由于ref的改变没有触发重新渲染,它仍然显示旧的ref值。
这显然不是很好,因为如果 something else 触发重新渲染,比如说您有另一个具有连接状态值的输入,那么{prevValue.current}将重新渲染为当前{value},然后在技术上是错误的,因为它将显示当前值,而不是以前的值。
因此,尽管从技术上讲,它可以在这种用例中正常工作,但当您添加更多代码时,它很容易出现bug,而且很难将其完全覆盖

3gtaxfhh

3gtaxfhh2#

https://reactjs.org/docs/hooks-reference.html#useref useRef返回一个可变ref对象,该对象的.current属性初始化为传递的参数(initialValue). The returned object will persist for the full lifetime of the component
useEffect是否在每次渲染后运行?是的!默认情况下,它运行both after the first render and after every update
因此,它按顺序步骤发生:

kmpatx3s

kmpatx3s3#

useRef()用于在连续渲染中保存值。如果要保留过去的值,请将其放入onChange

<input
    value={value}
    onChange={e => {
       prevValue.current = value;
       setValue(e.target.value)
    }}
   />

这将在value的当前状态值被更改之前将其分配给它,并且您将不需要useEffect钩子。

相关问题