为什么 useRef 值是整数时动态更新,而当它是字符串时存储以前的值?
Why useRef value dynamically updates when it is an integer but stores the previous value when it is a string?
我刚刚学习了 useRef 并且对它的实际工作方式感到困惑。例如,
#1
function Ref() {
const rerenderCount = useRef(0);
useEffect(() => {
rerenderCount.current = rerenderCount.current + 1;
});
return <div>{rerenderCount.current}</div>;
}
此处,useRef 给出与以下代码中的 useState 相同的输出,#2
function State() {
const [rerenderCount, setRerenderCount] = useState(0);
useEffect(() => {
setRerenderCount(prevCount => prevCount + 1);
});
return <div>{rerenderCount}</div>;
}
但在#3 代码中,previousName.current 值始终显示以前的值。但是设置为name.
const [name, setName] = useState("");
const previousName = useRef(null);
useEffect(() => {
previousName.current = name;
}, [name]);
return (
<div className="App">
<input value={name} onChange={(e) => setName(e.target.value)} />
<div>
My name is {name} and it used to be {previousName.current}
</div>
</div>
);
请有人解释为什么名称后退了一步,其中整数更新及时。另外,useEffect中的[name]有什么用。有或没有它,我得到相同的结果和渲染计数。
在您的示例中,previousName
落后了一步,因为当您更改 name
状态时,组件将重新渲染,调用 useEffect 并更新 previousName
但这是最后一次更改不会导致新的渲染(useRef 不像 useState,组件不会重新渲染),因此您会看到 name
已正确更新但 previousName
具有与以前相同的值,即使它的值已经改变。
这是因为state的变化导致后续渲染时发生了previousName
的变化。
要查看其变化,需要额外的渲染。
为避免这种行为,您可以使用事件处理程序而不依赖于 useEffect 挂钩。
const handleChange = (text: string) => {
setName(text);
previousName.current = text;
};
return (
<div className="App">
<input value={name} onChange={(e) => handleChange(e.target.value)} />
<div>
My name is {name} and it used to be {previousName.current}
</div>
</div>
);
我刚刚学习了 useRef 并且对它的实际工作方式感到困惑。例如, #1
function Ref() {
const rerenderCount = useRef(0);
useEffect(() => {
rerenderCount.current = rerenderCount.current + 1;
});
return <div>{rerenderCount.current}</div>;
}
此处,useRef 给出与以下代码中的 useState 相同的输出,#2
function State() {
const [rerenderCount, setRerenderCount] = useState(0);
useEffect(() => {
setRerenderCount(prevCount => prevCount + 1);
});
return <div>{rerenderCount}</div>;
}
但在#3 代码中,previousName.current 值始终显示以前的值。但是设置为name.
const [name, setName] = useState("");
const previousName = useRef(null);
useEffect(() => {
previousName.current = name;
}, [name]);
return (
<div className="App">
<input value={name} onChange={(e) => setName(e.target.value)} />
<div>
My name is {name} and it used to be {previousName.current}
</div>
</div>
);
请有人解释为什么名称后退了一步,其中整数更新及时。另外,useEffect中的[name]有什么用。有或没有它,我得到相同的结果和渲染计数。
在您的示例中,previousName
落后了一步,因为当您更改 name
状态时,组件将重新渲染,调用 useEffect 并更新 previousName
但这是最后一次更改不会导致新的渲染(useRef 不像 useState,组件不会重新渲染),因此您会看到 name
已正确更新但 previousName
具有与以前相同的值,即使它的值已经改变。
这是因为state的变化导致后续渲染时发生了previousName
的变化。
要查看其变化,需要额外的渲染。
为避免这种行为,您可以使用事件处理程序而不依赖于 useEffect 挂钩。
const handleChange = (text: string) => {
setName(text);
previousName.current = text;
};
return (
<div className="App">
<input value={name} onChange={(e) => handleChange(e.target.value)} />
<div>
My name is {name} and it used to be {previousName.current}
</div>
</div>
);