目前我正在阅读react beta官方文档。
当我读到这部分时,我对在不同位置呈现组件的定义感到非常困惑。
// Code from official document
export default function Scoreboard() {
const [isPlayerA, setIsPlayerA] = useState(true);
return (
<div>
// If we use this pattern, the Counter state will not be preserved
{isPlayerA &&
<Counter person="Taylor" />
}
{!isPlayerA &&
<Counter person="Sarah" />
}
// If we use this pattern, the Counter state will be preserved
{/*isPlayerA ? <Counter person="Taylor" /> : <Counter person="Sarah" />*/}
<button onClick={() => {
setIsPlayerA(!isPlayerA);
}}>
Next player!
</button>
</div>
);
}
function Counter({ person }) {
...
}
在上面的例子中,计数器中的状态将被重置,因为文档说它们将被挂载在不同的位置。然而,我很困惑,为什么他们在不同的位置?为什么另一种条件呈现模式(参见上面的注释)可以保留状态?它们之间有什么区别?
我也做了一些实验,但更困惑了。
export default function Scoreboard() {
const [isPlayerA, setIsPlayerA] = useState(true);
return (
<div>
{isPlayerA && <div>Up</div>}
{isPlayerA ? <Counter person="Taylor" /> : <Counter person="Sarah" />}
{!isPlayerA && <div>Down</div>}
<button onClick={() => {
setIsPlayerA(!isPlayerA);
}}>
Next player!
</button>
</div>
);
}
在上述实验中,Counter状态也被保留。但是,当isPlayer
状态发生变化时,Counter分量的位置会发生变化。
然而,我很困惑,为什么他们在不同的位置?
{isPlayerA &&
<Counter person="Taylor" />
}
{!isPlayerA &&
<Counter person="Sarah" />
}
我认为你错过的主要事情是,当我们谈论节点的位置时,false
很重要。
这段代码产生2个子节点。如果isPlayerA为真,我们输出一个<Counter>
元素,然后是false
。如果isPlayerA为false,则两个子元素现在是false
,后跟一个<Counter>
元素。
既然第一个子元素的类型改变了(Counter ->False),它被卸载。由于第二个孩子已经改变了类型(false ->
以及为什么另一个条件呈现模式(参见上面的注释)可以保留状态?
{isPlayerA ? <Counter person="Taylor" /> : <Counter person="Sarah" />}
这段代码产生1个子节点。如果isPlayerA为true,则输出<Counter>
。如果isPlayerA为false,我们也输出一个<Counter>
。因为类型没有改变,所以不会发生卸载/重新挂载,react只是更新现有实例的props。
在上述实验中,Counter状态也被保留。然而,当isPlayer状态改变时,Counter组件将会在不同的位置。
{isPlayerA && <div>Up</div>}
{isPlayerA ? <Counter person="Taylor" /> : <Counter person="Sarah" />}
{!isPlayerA && <div>Down</div>}
在此代码中,您有3个节点。第一个参数要么为false,要么为div。第二个参数总是一个Counter。第三个参数要么为false,要么为div。由于第二个参数始终是Counter,因此它永远不会重新装入。