Lifting State
A question that comes up often is how to pass state between components. The answer is to lift the state up to the closest common ancestor and sharing it.
This is relatively easy to do. When multiple components need to use the state, we just define it higher up and then pass it down. Let's walk through an example:
Imagine you have two components: first is an input component (let's say for favorite animal) which stores the value typed inside of it within its own state. Next to it is a display div, which right now just says 'hi Jake!'. These two are sibling components:
function FavoriteAnimal(){
const [animal, setAnimal] = React.useState('')
return (
<div>
<label htmlFor="animal">Favorite Animal: </label>
<input id="animal" value={animal} onChange={event => setAnimal(event.target.value)} />
</div>)
}
function Display({animal}) {
return <div>{`Hi Jake!`}</div>
}
export default function App() {
return (
<form>
<FavoriteAnimal />
<Display />
</form>
);
}
The Animal
component knows its own state, but the app doesn't, nor does the Display
component. If we wanted to show the value of our favorite animal in the display, we would need to lift state into the App:
function FavoriteAnimal({animal, onAnimalChange}) {
return (
<div>
<label htmlFor="animal">Favorite Animal: </label>
<input id="animal" value={animal} onChange={onAnimalChange} />
</div>
)
}
function Display({animal}) {
return <div>{`Hi Jake! Your favorite animal is ${animal}`}</div>
}
export default function App() {
const [animal, setAnimal] = React.useState('')
return (
<form>
<FavoriteAnimal
animal={animal}
onAnimalChange={event => setAnimal(event.target.value)}
/>
<Display animal={animal} />
</form>
)
}
In this example, you can see we're defining the [animal, setAnimal]
state inside App
, and then passing the necessary pieces down to the FavoriteAnimal
and Display
components.