Подъем состояний в React
Часто несколько компонентов должны отражать одни и те же изменяющиеся данные. В React рекомендовано поднимать общее состояние до ближайшего общего предка. Давайте посмотрим на примере.
Пусть мы хотим сделать калькулятор температуры воды. Он будет представлять собой инпут, в который пользователь будет вводить температуру, и абзац, в который будет выводится вердикт: вода жидкая, вода твердая, вода газообразная.
Пусть наш калькулятор представляет собой
компонент-контейнер Calculator:
function Calculator() {
return <div>
</div>;
}
Вынесем инпут для ввода температуры в компонент
TempInp, а абзац с вердиктом - в компонент
Verdict:
function Calculator() {
return <div>
<Verdict />
<TempInp />
</div>;
}
Легко понять, что и TempInp, и Verdict должны
иметь стейт с температурой. При этом логично,
что это должна быть одна и та же температура:
по мере ввода данных в инпут должен
отображаться вердикт.
В таком случае рекомендовано использовать прием, называемый подъем состояния: состояние, общее для двух (и более) компонентов поднимается вверх до их общего родителя.
В нашем случае получится, что стейт с температурой
должен принадлежать компоненту Calculator,
который будет передавать его в TempInp и
Verdict в качестве пропсов:
function Calculator() {
const [temp, setTemp] = useState(0);
return <div>
<Verdict temp={temp} />
<TempInp temp={temp} />
</div>;
}
В компоненте TempInp должен быть инпут
для изменения температуры. Но, так как эта
температура является пропсом данного компонента,
то непосредственно в TempInp изменять
его нельзя. Правильно будет передать из компонента
Calculator специальную функцию для
изменения температуры:
function Calculator() {
const [temp, setTemp] = useState(0);
function changeTemp(event) {
setTemp(event.target.value);
}
return <div>
<Verdict temp={temp} />
<TempInp temp={temp} changeTemp={changeTemp} />
</div>;
}
Можно, кстати, не вводить новую функцию,
а передать в дочерний компонент функцию setTemp:
function Calculator() {
const [temp, setTemp] = useState(0);
return <div>
<Verdict temp={temp} />
<TempInp temp={temp} setTemp={setTemp} />
</div>;
}
Напишите реализацию компонентов TempInp
и Verdict.
Придумайте 3 задачи, в которых нужно
использовать подъем состояния. Напишите решения
этих задач.