Praca z inputami w React
Praca z inputami w React odbywa się za pomocą
stanów. Każdemu inputowi przypisywany jest własny
stan, zawierający value inputa.
Spójrzmy na przykład. Załóżmy, że mamy input:
function App() {
return <div>
<input />
</div>;
}
Załóżmy również, że mamy stan:
function App() {
const [value, setValue] = useState('text');
return <div>
<input />
</div>;
}
Przywiążmy nasz stan do atrybutu value
inputa:
function App() {
const [value, setValue] = useState('text');
return <div>
<input value={value} />
</div>;
}
W takim przypadku okaże się, że przy zmianie stanu, reaktywnie zmieni się również tekst inputa.
Daje to jednak ciekawy efekt uboczny:
teraz po uruchomieniu kodu w przeglądarce w inputcie
nie da się zmienić tekstu! Dlaczego: ponieważ
przy wprowadzaniu tekstu do inputa nie zmienia się
stan value, odpowiednio, i tekst
w inputcie nie powinien się zmieniać.
Spróbuj sam. Skopiuj mój kod i uruchom u siebie. Spróbuj zmieniać tekst w inputcie - nic ci nie wyjdzie. Otwórz konsolę przeglądarki - zobaczysz w niej ostrzeżenie React. To ostrzeżenie wskazuje nam, że powiązaliśmy stan z inputem, ale tym samym zablokowaliśmy input.
Zróbmy tak, aby do naszego inputa można było wprowadzać tekst. Aby to zrobić, trzeba sprawić, aby przy wprowadzaniu zmieniał się nasz stan na aktualną wartość inputa.
Na początek trzeba na input nałożyć
zdarzenie onChange:
function App() {
const [value, setValue] = useState('text');
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
To zdarzenie w React zachowuje się inaczej w porównaniu z czystym JS. W React wyzwala się natychmiast po zmianie inputa. To znaczy przy wprowadzaniu lub usuwaniu symbolu.
Dodajmy teraz handler naszego zdarzenia:
function App() {
const [value, setValue] = useState('text');
function handleChange() {
}
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
W tym handlerze powinniśmy odczytać aktualny
tekst inputa i ustawić go w stanie za pomocą
funkcji setValue.
Problem w tym, że this tej funkcji
nie będzie wskazywać na nasz input - taka jest
specyfika React. Aby otrzymać element,
w którym zdarzyło się zdarzenie, musimy
użyć event.target:
function App() {
const [value, setValue] = useState('text');
function handleChange(event) {
console.log(event.target); // odniesienie do elementu DOM inputa
}
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
Wypiszmy za pomocą event.target aktualny
tekst inputa:
function App() {
const [value, setValue] = useState('text');
function handleChange(event) {
console.log(event.target.value); // aktualny tekst inputa
}
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
A teraz zapiszmy tekst inputa do naszego stanu:
function App() {
const [value, setValue] = useState('text');
function handleChange(event) {
setValue(event.target.value);
}
return <div>
<input value={value} onChange={handleChange} />
</div>;
}
Teraz będziemy mogli wprowadzać tekst do inputa. Przy
tym stan value zawsze będzie zawierać
aktualny tekst inputa.
Możemy się łatwo o tym przekonać. Wypiszmy zawartość naszego tekstu w akapicie. W tym przypadku przy wprowadzaniu tekstu do inputa wprowadzony tekst będzie automatycznie pojawiać się w akapicie:
function App() {
const [value, setValue] = useState('');
function handleChange(event) {
setValue(event.target.value);
}
return <div>
<input value={value} onChange={handleChange} />
<p>text: {value}</p>
</div>;
}
Możemy przepisać na bardziej kompaktowy wariant z anonimową funkcją strzałkową:
function App() {
const [value, setValue] = useState('');
return <div>
<input value={value} onChange={event => setValue(event.target.value)} />
<p>text: {value}</p>
</div>;
}
Tak więc, do pracy dowolnego inputa
potrzebujemy następującego: stworzyć stan dla tego
inputa, powiązać stan z atrybutem value
inputa, nałożyć zdarzenie onChange na input,
w handlerze zdarzenia zmieniać stan inputa
na jego tekst.
Te operacje trzeba będzie przeprowadzać z każdym
inputem. To znaczy, jeśli masz dwa inputy,
to będziesz mieć dwa stany i dwie funkcje-handlery
zdarzenia onChange.
Zrób dwa inputy. Niech tekst pierwszego inputa wypisuje się w pierwszym akapicie, a tekst drugiego inputa - w drugim akapicie.