Podnoszenie stanu w React

Często kilka komponentów musi odzwierciedlać te same zmieniające się dane. W React zaleca się podnoszenie wspólnego stanu do najbliższego wspólnego przodka. Spójrzmy na przykład.

Załóżmy, że chcemy zrobić kalkulator temperatury wody. Będzie on reprezentował input, do którego użytkownik będzie wprowadzał temperaturę, oraz akapit, w którym będzie wyświetlana ocena: woda jest ciekła, woda jest stała, woda jest gazem.

Załóżmy, że nasz kalkulator reprezentuje komponent-kontener Calculator:

jsxfunction Calculator() {
  return <div>
    
  </div>;
}

Wyniesmy input do wprowadzania temperatury do komponentu TempInp, a akapit z oceną - do komponentu Verdict:

jsxfunction Calculator() {
  return <div>
    <Verdict />
    <TempInp />
  </div>;
}

Łatwo zrozumieć, że zarówno TempInp, jak i Verdict muszą mieć stan z temperaturą. Przy tym logiczne jest, że powinna to być jedna i ta sama temperatura: w miarę wprowadzania danych do inputu powinna być wyświetlana ocena.

W takim przypadku zaleca się użycie techniki, zwanej podnoszeniem stanu: stan, wspólny dla dwóch (lub więcej) komponentów, jest podnoszony w górę do ich wspólnego rodzica.

W naszym przypadku okaże się, że stan z temperaturą powinien należeć do komponentu Calculator, który będzie przekazywał go do TempInp i Verdict w postaci propsów:

jsxfunction Calculator() {
  const [temp, setTemp] = useState(0);
  
  return <div>
    <Verdict temp={temp} />
    <TempInp temp={temp} />
  </div>;
}

W komponencie TempInp powinien znajdować się input do zmiany temperatury. Ale, ponieważ temperatura ta jest propsem tego komponentu, to bezpośrednio w TempInp nie można jej zmieniać. Właściwie będzie przekazać z komponentu Calculator specjalną funkcję do zmiany temperatury:

jsxfunction Calculator() {
  const [temp, setTemp] = useState(0);
  
  function changeTemp(event) {
    setTemp(event.target.value);
  }
  
  return <div>
    <Verdict temp={temp} />
    <TempInp temp={temp} changeTemp={changeTemp} />
  </div>;
}

Można, przy okazji, nie wprowadzać nowej funkcji, a przekazać do komponentu potomnego funkcję setTemp:

jsxfunction Calculator() {
  const [temp, setTemp] = useState(0);
  
  return <div>
    <Verdict temp={temp} />
    <TempInp temp={temp} setTemp={setTemp} />
  </div>;
}
Задание 1

Napisz implementację komponentów TempInp i Verdict.

Задание 2

Wymyśl 3 zadania, w których trzeba używać podnoszenia stanu. Napisz rozwiązania tych zadań.