Aby aplikacja mogła dynamicznie reagować na interakcje użytkownika, musi aktualizować swój widok w oparciu o dane, które mogą się zmieniać w czasie. React realizuje to za pomocą mechanizmu znanego jako Stan (State), który pozwala aplikacji na aktualizację bez konieczności jej przeładowania (https://react.dev/learn/state-a-components-memory).

React hooks

Hooki to specjalne funkcje w React, używane wyłącznie w komponentach. Wprowadzają one dodatkowe mechanizmy do aplikacji. Wszystkie hooki rozpoczynają się od słowa use, a pełny ich spis dostępny jest w dokumentacji React.

useState

Funkcja useState dostarcza mechanizm stanu. Wywołując tę funkcję, tworzymy zmienną stanu, którą React „śledzi”.

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Liczba kliknięć: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Kliknij mnie
      </button>
    </div>
  );
}

Podczas wywoływania useState, określamy wartość początkową, a w rezultacie otrzymujemy dwuelementową tablicę. Pierwszy element tej tablicy to aktualna wartość zmiennej, a drugi to funkcja służąca do aktualizacji tej zmiennej.

Proces aktualizacji stanu:

Po każdej aktualizacji stanu, React ponownie wykonuje komponent funkcyjny, w którym został wywołany useState, oraz wszystkie jego komponenty potomne. Podczas tej aktualizacji React wylicza wszystkie wartości na nowo, aktualizuje Virtual DOM i sprawdza, czy potrzebna jest aktualizacja Real DOM.

Nazewnictwo

useState zwraca tablicę z dwoma wartościami:

  • Pierwszy element to aktualna wartość stanu. Nazwa powinna opisywać, co przechowuje stan; unikaj ogólnych nazw, takich jak value czy x.
  • Drugi element to funkcja aktualizująca stan; zazwyczaj dodaje się przedrostek set do nazwy pierwszego elementu, np. setEmail, setUserName.

Typy danych

Funkcja useState akceptuje jeden argument, który może być dowolnego typu dostępnego w JavaScript, zarówno prostego (takiego jak Number, String, czy Boolean), jak i referencyjnego (np. obiekty czy tablice). Ważne jest, aby pamiętać, że przy aktualizacji stanu należy podać pełną nową wartość – nawet jeśli w obiekcie zmieni się tylko jeden atrybut, konieczne jest podanie całego obiektu, aby uniknąć nadpisania.

Przykład gdzie nadpiszemy obiekt:

import React, { useState } from 'react';

function UserProfile() {
  const [user, setUser] = useState({ name: 'Jan', surname: 'Kowalski' });

  const updateName = () => {
    setUser({ name: 'Adam' });
  };

  return (
    <div>
      <p>Imię: {user.name}</p>
      <p>Nazwisko: {user.surname}</p>
      <button onClick={updateName}>Zmień imię na Adam</button>
    </div>
  );
}

Poprawny sposób aktualizacji obiektu:

import React, { useState } from 'react';

function UserProfile() {
  const [user, setUser] = useState({ name: 'Jan', surname: 'Kowalski' });
  
  const updateName = () => {
    setUser(prevUser => ({ ...prevUser, name: 'Adam' }));
  };

  const updateSurname = () => {
    setUser(prevUser => ({ ...prevUser, surname: 'Nowak' }));
  };

  return (
    <div>
      <p>Imię: {user.name}</p>
      <p>Nazwisko: {user.surname}</p>
      <button onClick={updateName}>Zmień imię na Adam</button>
      <button onClick={updateSurname}>Zmień nazwisko na Nowak</button>
    </div>
  );
}

Wiązanie dwukierunkowe – two-way binding

Wiązanie dwukierunkowe to technika w programowaniu interfejsów użytkownika, która synchronizuje stan elementu interfejsu (np. pola formularza) z modelem danych (stanem komponentu). Umożliwia to, aby zmiany w jednym miejscu (interfejsie użytkownika lub stanie) były automatycznie odzwierciedlane w drugim, zapewniając spójność i interaktywność.

import React, { useState } from 'react';

export default function SimpleInput() {
  const [inputValue, setInputValue] = useState('');

  const handleInputChange = (e) => {
    setInputValue(e.target.value);
  };

  return (
    <div>
      <input
        type="text"
        value={inputValue}
        onChange={handleInputChange}
      />
    </div>
  );
}

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *