useRef 存储以前的状态值
useRef to store previous state value
我对下面使用 useRef 存储先前状态值的用法感到困惑。本质上,它如何能够正确显示先前的值。由于 useEffect 依赖于“值”,我的理解是每次“值”发生变化时(即当用户更新文本框时),它会将“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>
);
}
useRef()
用于在连续渲染中保留值。如果你想保留过去的价值把它放在 onChange
:
<input
value={value}
onChange={e => {
prevValue.current = value;
setValue(e.target.value)
}}
/>
这将在更改之前将其分配给 value
的当前状态值,您将不需要 useEffect
挂钩。
好的,虽然这在技术上是可行的,但这是一种令人困惑的方法,并且可能会在您添加更多内容时导致错误。它起作用的原因是因为 useEffect
在 状态更改后运行 ,并且更改 ref 值不会导致重新渲染。更好的方法是在 onChange
处理程序期间更新 ref 值,而不是在效果中。但是您发布的代码的工作方式如下:
- 最初,两者都是空的
- 用户键入内容,通过
setValue
触发状态更改
- 这会触发重新渲染,因此
{value}
是新值,但由于 ref 尚未更新,{prevValue.current}
仍将渲染为 old价值
- 接下来,在渲染之后,效果将运行,因为它具有
value
作为依赖项。所以这个效果更新 ref 以包含 CURRENT 状态值
- 但是,由于更改 ref 值不会触发重新渲染,因此新值不会反映在渲染的内容中
因此,一旦上述步骤完成,从技术上讲,状态值和 ref 是相同的值。但是,由于 ref 更改没有触发重新渲染,它仍然在渲染的内容中显示旧的 ref 值。
这显然不是很好,因为如果 其他东西 触发重新渲染,比如你有另一个具有连接状态值的输入,那么是的 {prevValue.current}
然后会重新呈现为当前 {value}
然后技术上是错误的因为它会显示当前值,而不是以前的值。
因此,虽然它在技术上适用于此用例,但随着您添加更多代码,它很容易出现错误,并且难以理解
https://reactjs.org/docs/hooks-reference.html#useref
useRef
returns 一个可变的 ref 对象,其 .current 属性 被初始化为传递的参数 (initialValue)。 The returned object will persist for the full lifetime of the component
.
https://reactjs.org/docs/hooks-effect.html
每次渲染后是否使用 Effect 运行?是的!默认情况下,它 运行s both after the first render and after every update
所以它按顺序发生:
1 - Input change (example: "1")
2 - Component re-render
3 - useEffect run and set value ("1") to prevValue.current. This does not make component re-render. At this time prevValue.current is "1".
4 - Input change (example: "12")
5 - Component re-render => show prevValue.current was set before in step 3 ("1")
6 - useEffect run and set value ("12") to prevValue.current. This does not make component re-render. At this time prevValue.current is "12".
...
我对下面使用 useRef 存储先前状态值的用法感到困惑。本质上,它如何能够正确显示先前的值。由于 useEffect 依赖于“值”,我的理解是每次“值”发生变化时(即当用户更新文本框时),它会将“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>
);
}
useRef()
用于在连续渲染中保留值。如果你想保留过去的价值把它放在 onChange
:
<input
value={value}
onChange={e => {
prevValue.current = value;
setValue(e.target.value)
}}
/>
这将在更改之前将其分配给 value
的当前状态值,您将不需要 useEffect
挂钩。
好的,虽然这在技术上是可行的,但这是一种令人困惑的方法,并且可能会在您添加更多内容时导致错误。它起作用的原因是因为 useEffect
在 状态更改后运行 ,并且更改 ref 值不会导致重新渲染。更好的方法是在 onChange
处理程序期间更新 ref 值,而不是在效果中。但是您发布的代码的工作方式如下:
- 最初,两者都是空的
- 用户键入内容,通过
setValue
触发状态更改
- 这会触发重新渲染,因此
{value}
是新值,但由于 ref 尚未更新,{prevValue.current}
仍将渲染为 old价值 - 接下来,在渲染之后,效果将运行,因为它具有
value
作为依赖项。所以这个效果更新 ref 以包含 CURRENT 状态值 - 但是,由于更改 ref 值不会触发重新渲染,因此新值不会反映在渲染的内容中
因此,一旦上述步骤完成,从技术上讲,状态值和 ref 是相同的值。但是,由于 ref 更改没有触发重新渲染,它仍然在渲染的内容中显示旧的 ref 值。
这显然不是很好,因为如果 其他东西 触发重新渲染,比如你有另一个具有连接状态值的输入,那么是的 {prevValue.current}
然后会重新呈现为当前 {value}
然后技术上是错误的因为它会显示当前值,而不是以前的值。
因此,虽然它在技术上适用于此用例,但随着您添加更多代码,它很容易出现错误,并且难以理解
https://reactjs.org/docs/hooks-reference.html#useref
useRef
returns 一个可变的 ref 对象,其 .current 属性 被初始化为传递的参数 (initialValue)。 The returned object will persist for the full lifetime of the component
.
https://reactjs.org/docs/hooks-effect.html
每次渲染后是否使用 Effect 运行?是的!默认情况下,它 运行s both after the first render and after every update
所以它按顺序发生:
1 - Input change (example: "1")
2 - Component re-render
3 - useEffect run and set value ("1") to prevValue.current. This does not make component re-render. At this time prevValue.current is "1".
4 - Input change (example: "12")
5 - Component re-render => show prevValue.current was set before in step 3 ("1")
6 - useEffect run and set value ("12") to prevValue.current. This does not make component re-render. At this time prevValue.current is "12".
...