Tilojen nostaminen Reactissa

Usein useiden komponenttien tulee heijastaa samoja muuttuvia tietoja. Reactissa suositellaan yhteisen tilan nostamista lähimpään yhteiseen esi-isään. Katsotaanpa esimerkkiä.

Oletetaan, että haluamme tehdä veden lämpötilan laskurin. Se koostuu syöttökentästä, johon käyttäjä syöttää lämpötilan, ja kappaleesta, johon tulostetaan päätelmä: vesi on nestemäistä, vesi on kiinteää, vesi on kaasumaista.

Oletetaan, että laskurimme on säiliökomponentti Calculator:

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

Erotetaan lämpötilan syöttökenttä komponenttiin TempInp, ja päätelmäkappale - komponenttiin Verdict:

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

On helppo ymmärtää, että sekä TempInp että Verdict tarvitsevat tilan lämpötilalle. Samaan aikaan on loogista, että sen tulisi olla sama lämpötila: kun tietoja syötetään syöttökenttään, päätelmän tulisi näkyä.

Tässä tapauksessa suositellaan käyttämään tekniikkaa, jota kutsutaan tilan nostamiseksi: tila, joka on yhteinen kahdelle (tai useammalle) komponentille, nostetaan ylös niiden yhteiseen vanhempaan.

Meidän tapauksessamme käy niin, että lämpötilatila kuuluu komponentille Calculator, joka välittää sen TempInp:lle ja Verdict:lle propseina:

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

Komponentissa TempInp tulee olla syöttökenttä lämpötilan muuttamiseen. Mutta koska tämä lämpötila on tämän komponentin props, sitä ei voida suoraan muuttaa TempInp:ssä. Oikea tapa on välittää komponentista Calculator erityinen funktio lämpötilan muuttamiseksi:

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>;
}

Voit muuten olla ottamatta käyttöön uutta funktiota, vaan välittää lapsikomponenttiin funktion setTemp:

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

Kirjoita komponenttien TempInp ja Verdict toteutus.

Задание 2

Keksi 3 tehtävää, joissa tarvitaan tilan nostamista. Kirjoita näiden tehtävien ratkaisut.