对 state 保留或重置
核心概念,当同一个组件在渲染树中同样的位置加载时,组件中的状态会被保留
本文使用 react
官方示例
不同位置渲染相同的组件
jsx
import { useState } from "react";
export default function App() {
const counter = <Counter />;
return (
<div>
{counter}
{counter}
</div>
);
}
function Counter() {
const [score, setScore] = useState(0);
const [hover, setHover] = useState(false);
let className = "counter";
if (hover) {
className += " hover";
}
return (
<div
className={className}
onPointerEnter={() => setHover(true)}
onPointerLeave={() => setHover(false)}
>
<h1>{score}</h1>
<button onClick={() => setScore(score + 1)}>加一</button>
</div>
);
}
同一组件在不同位置渲染,它们有独立的状态
同一位置渲染同一个组件
jsx
import { useState } from "react";
export default function App() {
const [isFancy, setIsFancy] = useState(false);
return (
<div>
{isFancy ? <Counter isFancy={true} /> : <Counter isFancy={false} />}
<label>
<input
type="checkbox"
checked={isFancy}
onChange={(e) => {
setIsFancy(e.target.checked);
}}
/>
使用好看的样式
</label>
</div>
);
}
function Counter({ isFancy }) {
const [score, setScore] = useState(0);
const [hover, setHover] = useState(false);
let className = "counter";
if (hover) {
className += " hover";
}
if (isFancy) {
className += " fancy";
}
return (
<div
className={className}
onPointerEnter={() => setHover(true)}
onPointerLeave={() => setHover(false)}
>
<h1>{score}</h1>
<button onClick={() => setScore(score + 1)}>加一</button>
</div>
);
}
当切换样式时,虽然通过 condition ? expressionA : expressionB
分发了 Counter
组件,但是是基于同一个位置的同一组件渲染,状态被保留下来
渲染同一个组件时,如何重置状态
渲染在不同的位置
jsx
import { useState } from "react";
export default function Scoreboard() {
const [isPlayerA, setIsPlayerA] = useState(true);
return (
<div>
{isPlayerA && <Counter person="Taylor" />}
{!isPlayerA && <Counter person="Sarah" />}
<button
onClick={() => {
setIsPlayerA(!isPlayerA);
}}
>
下一位玩家!
</button>
</div>
);
}
function Counter({ person }) {
const [score, setScore] = useState(0);
const [hover, setHover] = useState(false);
let className = "counter";
if (hover) {
className += " hover";
}
return (
<div
className={className}
onPointerEnter={() => setHover(true)}
onPointerLeave={() => setHover(false)}
>
<h1>
{person} 的分数:{score}
</h1>
<button onClick={() => setScore(score + 1)}>加一</button>
</div>
);
}
在组件上使用不同的 key
值
jsx
import { useState } from "react";
export default function Scoreboard() {
const [isPlayerA, setIsPlayerA] = useState(true);
return (
<div>
{isPlayerA ? (
<Counter key="Taylor" person="Taylor" />
) : (
<Counter key="Sarah" person="Sarah" />
)}
<button
onClick={() => {
setIsPlayerA(!isPlayerA);
}}
>
下一位玩家!
</button>
</div>
);
}
function Counter({ person }) {
const [score, setScore] = useState(0);
const [hover, setHover] = useState(false);
let className = "counter";
if (hover) {
className += " hover";
}
return (
<div
className={className}
onPointerEnter={() => setHover(true)}
onPointerLeave={() => setHover(false)}
>
<h1>
{person} 的分数:{score}
</h1>
<button onClick={() => setScore(score + 1)}>加一</button>
</div>
);
}