Hak useContext został wprowadzony jako część API React Hooks w React 16.8. Przed jego wprowadzeniem zarządzanie stanem globalnym w aplikacjach React zazwyczaj wymagało bibliotek takich jak Redux lub Context API z podejściem dostawcy/konsumenta kontekstu opartego na klasach.

React dostrzegł potrzebę zaoferowania prostszego, alternatywnego sposobu udostępniania wartości, takich jak motywy, dane użytkownika i inne informacje, pomiędzy komponentami, ponieważ poprzednie rozwiązanie było raczej kłopotliwe i czasami wydawało się, że trzeba było bez końca przekazywać rekwizyty w dół głębokiej hierarchii komponentów. useContext zapewnia znacznie bardziej intuicyjną metodę uzyskiwania dostępu do globalnego stanu naszej aplikacji bez bardziej złożonego podejścia opartego na Redux.

Co to jest kontekst?

Aby użyć UseContext, musimy najpierw utworzyć plik kontekstowy w naszej aplikacji React. W React „kontekst” ma specyficzne znaczenie: umożliwia przekazywanie danych przez drzewo komponentów bez konieczności ręcznego przekazywania rekwizytów na każdym poziomie. Może reprezentować różne typy informacji:

  • Stan aplikacji:informacje o bieżącym stanie aplikacji, takie jak informacje o użytkowniku, preferencje i ustawienia.
  • Dane środowiskowe: szczegółowe informacje o bieżącym systemie lub środowisku, takie jak punkty końcowe interfejsu API, konfiguracje systemu lub możliwości urządzenia.
  • Stan operacyjny: reprezentuje obecny stan w danym zakresie, np. bieżący użytkownik, aktywny modal lub wybrany motyw.

Jak utworzyć plik kontekstowy

W praktyce plik kontekstowy to po prostu plik .js, który zwykle przechowujesz w folderze „Contexts” w folderze src aplikacji React. Wyglądem przypomina typowy, funkcjonalny element. Spójrzmy na przykład, jak należy to wdrożyć:

import React, { createContext, useContext, useState } from 'react';

const UserContext = createContext();

export const UserProvider = ({ children }) => {
    const [user, setUser] = useState({
        name: 'Jane',
        surname: 'Doe',
        address: '123 React St, Hooks City',
        //...other details
    });

    return (
        <UserContext.Provider value={{ user, setUser }}>
            {children}
        </UserContext.Provider>
    );
};

Tutaj tworzymy nowy kontekst za pomocą createContext(). Spowoduje to zwrócenie obiektu z Provider i Consumer. W kontekście nowoczesnego Reacta z hakami, Consumer nie jest używane tak często, ponieważ hak useContext zapewnia prostszy sposób wykorzystania wartości kontekstowych.

Następnie deklarujemy i eksportujemy UserProvider. Ten komponent jest zasadniczo opakowaniem. Kiedy komponenty są w nim opakowane (dzieci), uzyskują one możliwość dostępu i potencjalnej modyfikacji stanu user, w zależności od tego, jak jest on zaimplementowany w komponentach potomnych. Wewnątrz znajduje się zmienna stanu. To właśnie w tym stanie tworzymy obiekt do przechowywania i śledzenia wszystkich zmiennych, które chcemy udostępnić wszystkim komponentom potomnym, które go subskrybują.

Zwrócony element ‹UserContext.Provider› faktycznie dostarcza dane do komponentów podrzędnych. Pobiera valueprop, który konkretnie określa, jakie dane należy dostarczyć. W tym kontekście dostępne są zarówno user, jak i setUser, dzięki czemu możemy zarówno czytać, jak i modyfikować kontekst.

Jak korzystać z UseContect

Aby użyć kontekstu, takiego jak ten, który utworzyliśmy wcześniej, musimy umieścić komponenty wymagające dostępu do tych informacji w komponencie UserProvider. Może to być cały komponent aplikacji lub podkomponent w części aplikacji, w której potrzebne są te informacje w jej hierarchii elementów podrzędnych. Spójrzmy na przykład:

import React from 'react';
import { UserProvider } from './contexts/UserContext'; 
import BioCard from './components/BioCard'; 

function App() {
  return (
    <UserProvider>
      <header>
        <h1>Welcome to My App</h1>
      </header>
      <main>
        <BioCard />
        {/* Maybe some routes or other components */}
      </main>
      <footer>
        App Footer
      </footer>
    </UserProvider>
  );
}

export default App;

Tutaj zawinęliśmy cały katalog główny naszej aplikacji w pliku UserProvider. Oznacza to, że każdy pojedynczy komponent ma teraz dostęp do informacji userContext. Importujemy również niestandardowy komponent o nazwie BioCard. Przyjrzyjmy się, jak ten komponent może pobierać informacje z kontekstu:

import React, { useContext } from 'react';
import { UserContext } from '../contexts/UserContext';

function BioCard() {
  const { user } = useContext(UserContext); // Destructure user from the context value

  return (
    <div className="bio-card">
      <h2>{user.name} {user.surname}</h2>
      <p>Address: {user.address}</p>
      {/* Display other user details as required */}
    </div>
  );
}

export default BioCard;

Tutaj zaimportowaliśmy useContext z React i UserContext z pliku, w którym je zdefiniowałeś. W komponencie używamy wywołania useContext(UserContext), aby uzyskać dostęp do danych użytkownika (i wszelkich innych wartości podanych w kontekście). Następnie komponent BioCard wyświetla informacje o użytkowniku, korzystając z tych danych.

Po uruchomieniu aplikacji BioCard będzie miał dostęp do danych użytkownika dostarczonych przez UserProvider i wyświetli kartę z informacjami o tym użytkowniku.

Wniosek

W tym przewodniku zagłębiliśmy się w hak useContext, podkreślając jego rolę w globalnym zarządzaniu stanem w React. Przeszliśmy przez proces tworzenia UserContext, zademonstrowaliśmy jego implementację, zawijając nasz główny App w UserProvider i pokazaliśmy, jak komponent BioCard może łatwo uzyskać dostęp do informacji o użytkowniku i wyświetlić je z kontekstu.