[英]Official React Tutorial, using Hooks - Component Not Updating
我开始使用钩子重新创建官方的React Tutorial。
我遇到了两个我正在努力解决的问题。
有关完整代码,请参阅CodePen,包括行号。
完整代码
问题1
// Click handler
function handleClick(e) {
e.preventDefault();
// console.log('1) Inside Square click handler');
props.onUpdate();
// Logs un-updated value, probably because setState is async
console.log("props.value", props.value);
// STACKOVERFLOW QUESTION (Line 18)
// This still logs un-updated value (null). Why?
// PS: Line 23 logs the right value
window.setTimeout(() => {
console.log("props.value after timeout", props.value);
}, 1000);
}
// Logs correct value (Line 23)
console.log("props.value outside", props.value);
第18 setTimeout
从处理程序中记录传递的prop
。 我知道state
是异步设置的,在第9行(来自父级的回调)。 我知道第12行会在异步state
更新之前记录该值,但我不明白为什么超时仍会输出错误的值。
问题2
<div className = "status" >
{
(() => {
console.log("rendering, status:", status);
return status;
})()
}
</div>
为什么第75和76行的status
不能反映最新的state
变化? 我在第62行设置它,然后直接更新state
,这反过来应该导致使用正确的值重新渲染。 我猜测答案是重新渲染再次运行整个功能组件,重置status
(即只保存state
)。 如果这是正确的,我们如何确切知道在每个state
/ prop
/ context
更新中重新呈现哪些组件?
我不是专家,所以可能有点不对劲。
为什么超时仍然打印错误的值。
功能组件(FC)与类组件(CC)的不同之处在于,1。在FC中, props
包含渲染后的快照值(使用JavaScript闭包)1。在CC中, props
甚至在渲染后包含更新的值(因为this.props
可以更改,因为this
不是不可变的)。
我刚刚阅读了功能组件与类不同的内容? ,昨天,这就是“错误”值, null
出现的方式。
最初, score
数组为[null x 9]
因此props.value
设置为null
。
function Board() {
const [isXNext, setIsXNext] = React.useState(true);
// Initialize array with null values
const initialArray = Array(9).fill(null);
const [score, setScore] = React.useState(initialArray);
// onUpdate handler includes index, thus have to be arrow function
function renderSquare(i) {
return <Square value={score[i]} onUpdate={() => handleUpdate(i)} />;
}
...
}
并且null
被关闭到window.setTimeout
因此props.value
在超时后仍然为null
。
function handleClick(e) {
...
window.setTimeout(() => {
console.log("props.value after timeout", props.value);
}, 1000);
}
为什么第75和76行的状态不能反映最新的状态变化?
status
是局部变量而不是React状态。
let status = `Next player: ${getPlayer()}`;
由于React不跟踪变量,因此不会重新呈现status
,如下所示。
status = "Winner: " + winner;
也许你可以将status
声明为状态,比如
const [status, setStatus] = React.useState(`Next player: ${getPlayer()}`);
并使用setStatus
更新状态
if (winner) {
setStatus("Winner: " + winner);
console.log("game-won status:", status);
}
如上所述,我昨天只读过Dan的文章,所以不能100%准确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.