To share between two sibling components we need to lift the state up
which basically amounts to finding the lowest
common parent shared between the two components and placing the state management
there, and then passing the state and a mechanism for updating that state down
into the components that need it.
function Name({
name,
onNameChange,
}: {
name: string;
onNameChange: ChangeEventHandler<HTMLInputElement>;
}) {
return (
<div>
<label htmlFor="name">Name: </label>
<input id="name" value={name} onChange={onNameChange} />
</div>
);
}
// π¨ accept `animal` and `onAnimalChange` props to this component
function FavoriteAnimal() {
// π£ delete this, it's now managed by the App
const [animal, setAnimal] = useState("");
return (
<div>
<label htmlFor="animal">Favorite Animal: </label>
<input
id="animal"
value={animal}
onChange={(event) => setAnimal(event.target.value)}
/>
</div>
);
}
// π¨ uncomment this
// function Display({name, animal}) {
// return <div>{`Hey ${name}, your favorite animal is: ${animal}!`}</div>
// }
// π£ remove this component in favor of the new one
function Display({ name }: { name: string }) {
return <div>{`Hey ${name}, you favorite animal`}</div>;
}
function App() {
// π¨ add a useState for the animal
const [name, setName] = useState("");
return (
<form>
<Name name={name} onNameChange={(event) => setName(event.target.value)} />
{/* π¨ pass the animal and onAnimalChange prop here (similar to the Name component above) */}
<FavoriteAnimal />
{/* π¨ pass the animal prop here */}
<Display name={name} />
</form>
);
}
Suppose we have a new feature request for the Display
component. We want to display the animal
the user selects. But that state is managed in a βsiblingβ component, so we have to move that management to the least common parent (App
) and then pass it down.
function Name({
name,
onNameChange,
}: {
name: string;
onNameChange: ChangeEventHandler<HTMLInputElement>;
}) {
return (
<div>
<label htmlFor="name">Name: </label>
<input id="name" value={name} onChange={onNameChange} />
</div>
);
}
function FavoriteAnimal({
animal,
onAnimalChange,
}: {
animal: string;
onAnimalChange: ChangeEventHandler<HTMLInputElement>;
}) {
return (
<div>
<label htmlFor="animal">Favorite Animal: </label>
<input id="animal" value={animal} onChange={onAnimalChange} />
</div>
);
}
function Display({ name, animal }: { name: string; animal: string }) {
return <div>{`Hey ${name}, your favorite animal is: ${animal}!`}</div>;
}
function App() {
const [name, setName] = useState("");
const [animal, setAnimal] = useState("");
return (
<form>
<Name name={name} onNameChange={(event) => setName(event.target.value)} />
<FavoriteAnimal
animal={animal}
onAnimalChange={(e) => {
setAnimal(() => e.target.value);
}}
/>
<Display name={name} animal={animal} />
</form>
);
}