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);
}}>
Next player!
</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}'s score: {score}</h1>
<button onClick={() => setScore(score + 1)}>
Add one
</button>
</div>
);
}
According to the description in React official document(https://react.dev/learn/preserving-and-resetting-state#option-1-rendering-a-component-in-different-positions), the two Counter components in the code above are located in different positions in the UI tree.
However, I think the two Counter components are always in the position of <div><Counter /><button /></div> no matter what the isPlayerA state value is.
How do the two Counter components exist in different positions in the UI tree?
-----------------------------------------------------------------------------------------------
import { useState } from 'react';
export default function Scoreboard() {
const [isPlayerA, setIsPlayerA] = useState(true);
return (
<div>
{isPlayerA ? (
<Counter person="Taylor" />
) : (
<Counter person="Sarah" />
)}
<button onClick={() => {
setIsPlayerA(!isPlayerA);
}}>
Next player!
</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}'s score: {score}</h1>
<button onClick={() => setScore(score + 1)}>
Add one
</button>
</div>
);
}
I expected it to work like the code above.
According to the description in React official document(https://react.dev/learn/preserving-and-resetting-state#option-1-rendering-a-component-in-different-positions), the two Counter components in the code above are located in different positions in the UI tree.
However, I think the two Counter components are always in the position of no matter what the isPlayerA state value is.
I think the thing you're missing is that false
is a value. When you render this:
<div>
{isPlayerA && <Counter person="Taylor" />}
{!isPlayerA && <Counter person="Sarah" />}
<button
onClick={() => {
setIsPlayerA(!isPlayerA);
}}
>
Next player!
</button>
</div>
... the div always has 3 children. It's either <Counter>
, false
, <button>
; or false
, <Counter>
, <button>
. So the counter moves from being the first child to the second child.
With this:
<div>
{isPlayerA ? <Counter person="Taylor" /> : <Counter person="Sarah" />}
<button
onClick={() => {
setIsPlayerA(!isPlayerA);
}}
>
Next player!
</button>
</div>
... the div always has 2 children; a <Counter>
and a <button>