当在树中相同的位置渲染相同的组件时,React 会一直保留着组件的 state
js
return (
<div>
<Counter />
{showB && <Counter />}
</div>
)
// 当 showB 为 false, 第二个计数器停止渲染,它的 state 完全消失了。这是因为 React 在移除一个组件时,也会销毁它的 state。
// 当 showB 再次为 true 时,另一个计数器及其 state 将从头开始初始化(score = 0)并被添加到 DOM 中。
js
return (
<div>
{isFancy ? <Counter isFancy={true} /> : <Counter isFancy={false} />}
</div>
)
// 当 isFancy 变化时,计数器 state 并没有被重置。
// 不管 isFancy 是 true 还是 false,组件返回的 div 的第一个子组件都是 <Counter />。
// 它是位于相同位置的相同组件,所以对 React 来说,它是同一个计数器。
如何在相同位置重置 state
js
return (
<div>
{isPlayerA ? (
<Counter person="Taylor" />
) : (
<Counter person="Sarah" />
)}
</div>
);
// Counter
const [score, setScore] = useState(0);
return (
<div>
<h1>{person} 的分数:{score}</h1>
<button onClick={() => setScore(score + 1)}>
加一
</button>
</div>
);
}
切换玩家时,分数会被保留下来。这两个 Counter 出现在相同的位置,所以 React 会认为它们是 同一个 Counter,只是传了不同的 person prop。
有两个方法可以在它们相互切换时重置 state:
- 将组件渲染在不同的位置
- 使用 key 赋予每个组件一个明确的身份
js
// 1. 将组件渲染在不同的位置
{ isPlayerA && <Counter person="Taylor" /> }
{ !isPlayerA && <Counter person="Sarah" /> }
// 2. 使用 key
{ isPlayerA ? (
<Counter key="Taylor" person="Taylor" />
) : (
<Counter key="Sarah" person="Sarah" />
)
}