提问人:DucanoidYoung 提问时间:11/17/2023 更新时间:11/17/2023 访问量:16
关于状态快照和从 react 文档重新渲染的问题
A question about Status Snapshot and re-rendering from react document
问:
React 文档中的一个问题:
下面的例子是我的理解:
- 更改时<输入>元素触发重新渲染
- 重新渲染后应更新状态“text”
- 在调用 handleSend() 时(设置了超时),“text” 保存初始值
- 执行回调 3 秒后,如果我们更改了输入框中的值,则应更新“text”,因为组件已经重新渲染。
在回调之前,重新渲染必须发生得更快,无法弄清楚为什么它仍然打印初始值,并且必须改用 useRef()。
import { useState, useRef } from 'react';
export default function Chat() {
const [text, setText] = useState('');
function handleSend() {
setTimeout(() => {
alert('Sending: ' + text);
}, 3000);
}
return (
<>
<input
value={text}
onChange={e => setText(e.target.value)}
/>
<button
onClick={handleSend}>
Send
</button>
</>
);
}
答:
1赞
Hiren F
11/17/2023
#1
我认为以上就是 Javascript 的工作原理。以下是我对这些现象的假设。
当你创建/定义一个函数时,它会为它分配一个引用,即使你的执行是延迟的,你也是以完整的值启动的。alert
handleSend
text
当你定义一个函数时,它类似于(你可以阅读它(这里))。因此,当它被调用时,它只调用该特定的引用函数。Object
它具有特定变量的旧值,因为状态也是引用,因此它不会读取更新的值,因为在函数定义中使用了较旧的引用作为值。
评论
0赞
DucanoidYoung
11/18/2023
那么在解决方案中使用最新的值会很奇怪,因为也应该保留函数定义中的值。alert('Sending: ' + textRef.current);
const textRef = useRef(text);
textRef.current
0赞
Hiren F
11/20/2023
值存储在引用的属性中,而 textRef 保持不变,但已更新。它类似于直接从状态更新 Object 属性的方式,它将在控制台中反映新值,但不会显示在渲染中。.current
0赞
DucanoidYoung
11/20/2023
哦,所以当超时函数执行时,引用仍然指向原始状态,尽管组件已被重新渲染,并且已经在那一刻创建了一个新状态,但它仍然在初始组件中查看(该组件已被卸载,可能会在一段时间后被回收)。我解释得对吗?text
text
0赞
Hiren F
11/20/2023
是的,你做到了。它是一切尽头的功能。因此,一切都像简单的 javascript 一样工作。重新渲染组件,重新定义事物。这就是他们的使用方式,也是。useMemo
useCallback
评论