Hrvatski

Ovladajte React Contextom za učinkovito upravljanje stanjem u vašim aplikacijama. Naučite kada koristiti Context, kako ga efektivno implementirati i izbjeći uobičajene zamke.

React Context: Sveobuhvatan vodič

React Context je moćna značajka koja vam omogućuje dijeljenje podataka između komponenti bez eksplicitnog prosljeđivanja propsa kroz svaku razinu stabla komponenti. Pruža način da određene vrijednosti učinite dostupnima svim komponentama u određenom podstablu. Ovaj vodič istražuje kada i kako učinkovito koristiti React Context, uz najbolje prakse i uobičajene zamke koje treba izbjegavati.

Razumijevanje problema: Prop Drilling

U složenim React aplikacijama možete naići na problem "prop drillinga". To se događa kada trebate proslijediti podatke iz roditeljske komponente duboko do ugniježđene podređene komponente. Da biste to učinili, morate proslijediti podatke kroz svaku posrednu komponentu, čak i ako te komponente ne trebaju te podatke. To može dovesti do:

Razmotrite ovaj pojednostavljeni primjer:


function App() {
  const user = { name: 'Alice', theme: 'dark' };
  return (
    <Layout user={user} />
  );
}

function Layout({ user }) {
  return (
    <Header user={user} />
  );
}

function Header({ user }) {
  return (
    <Navigation user={user} />
  );
}

function Navigation({ user }) {
  return (
    <Profile user={user} />
  );
}

function Profile({ user }) {
  return (
    <p>Welcome, {user.name}!
Theme: {user.theme}</p>
  );
}

U ovom primjeru, user objekt se prosljeđuje kroz nekoliko komponenti, iako ga zapravo koristi samo komponenta Profile. Ovo je klasičan slučaj prop drillinga.

Predstavljamo React Context

React Context pruža način za izbjegavanje prop drillinga tako što podatke čini dostupnima bilo kojoj komponenti u podstablu bez eksplicitnog prosljeđivanja kroz propse. Sastoji se od tri glavna dijela:

Kada koristiti React Context

React Context je posebno koristan za dijeljenje podataka koji se smatraju "globalnima" za stablo React komponenti. To može uključivati:

Važna razmatranja:

Kako koristiti React Context: Praktičan primjer

Vratimo se na primjer prop drillinga i riješimo ga koristeći React Context.

1. Stvorite Context

Prvo, stvorite kontekst koristeći React.createContext(). Ovaj kontekst će sadržavati korisničke podatke.


// UserContext.js
import React from 'react';

const UserContext = React.createContext(null); // Default value can be null or an initial user object

export default UserContext;

2. Stvorite Provider

Zatim, omotajte korijen vaše aplikacije (ili relevantno podstablo) s UserContext.Provider. Proslijedite user objekt kao value prop Provideru.


// App.js
import React from 'react';
import UserContext from './UserContext';
import Layout from './Layout';

function App() {
  const user = { name: 'Alice', theme: 'dark' };
  return (
    <UserContext.Provider value={user}>
      <Layout />
    </UserContext.Provider>
  );
}

export default App;

3. Koristite Context

Sada, komponenta Profile može pristupiti user podacima izravno iz konteksta koristeći useContext hook. Nema više prop drillinga!


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

function Profile() {
  const user = useContext(UserContext);

  return (
    <p>Welcome, {user.name}!
Theme: {user.theme}</p>
  );
}

export default Profile;

Posredne komponente (Layout, Header i Navigation) više ne trebaju primati user prop.


// Layout.js, Header.js, Navigation.js
import React from 'react';

function Layout({ children }) {
  return (
    <div>
      <Header />
      <main>{children}</main>
    </div>
  );
}

function Header() {
  return (<Navigation />);
}

function Navigation() {
  return (<Profile />);
}

export default Layout;

Napredna upotreba i najbolje prakse

1. Kombiniranje Contexta s useReducer

Za složenije upravljanje stanjem, možete kombinirati React Context s useReducer hookom. To vam omogućuje upravljanje ažuriranjima stanja na predvidljiviji i održiviji način. Kontekst pruža stanje, a reducer obrađuje prijelaze stanja na temelju poslanih akcija.


// ThemeContext.js
import React, { createContext, useReducer } from 'react';

const ThemeContext = createContext();

const initialState = { theme: 'light' };

const themeReducer = (state, action) => {
  switch (action.type) {
    case 'TOGGLE_THEME':
      return { ...state, theme: state.theme === 'light' ? 'dark' : 'light' };
    default:
      return state;
  }
};

function ThemeProvider({ children }) {
  const [state, dispatch] = useReducer(themeReducer, initialState);

  return (
    <ThemeContext.Provider value={{ ...state, dispatch }}>
      {children}
    </ThemeContext.Provider>
  );
}

export { ThemeContext, ThemeProvider };



// ThemeToggle.js
import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ThemeToggle() {
  const { theme, dispatch } = useContext(ThemeContext);

  return (
    <button onClick={() => dispatch({ type: 'TOGGLE_THEME' })}>
      Toggle Theme (Current: {theme})
    </button>
  );
}

export default ThemeToggle;



// App.js
import React from 'react';
import { ThemeProvider } from './ThemeContext';
import ThemeToggle from './ThemeToggle';

function App() {
  return (
    <ThemeProvider>
      <div>
        <ThemeToggle />
      </div>
    </ThemeProvider>
  );
}

export default App;

2. Više Konteksta

Možete koristiti više konteksta u svojoj aplikaciji ako imate različite vrste globalnih podataka za upravljanje. To pomaže u odvajanju briga i poboljšava organizaciju koda. Na primjer, mogli biste imati UserContext za autentifikaciju korisnika i ThemeContext za upravljanje temom aplikacije.

3. Optimizacija performansi

Kao što je ranije spomenuto, promjene konteksta mogu pokrenuti ponovno renderiranje u komponentama koje ga koriste. Za optimizaciju performansi, razmotrite sljedeće:

4. Korištenje prilagođenih hookova za pristup kontekstu

Stvorite prilagođene hookove kako biste enkapsulirali logiku za pristup i ažuriranje vrijednosti konteksta. To poboljšava čitljivost i održivost koda. Na primjer:


// useTheme.js
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme must be used within a ThemeProvider');
  }
  return context;
}

export default useTheme;



// MyComponent.js
import React from 'react';
import useTheme from './useTheme';

function MyComponent() {
  const { theme, dispatch } = useTheme();

  return (
    <div>
      Current Theme: {theme}
      <button onClick={() => dispatch({ type: 'TOGGLE_THEME' })}>
        Toggle Theme
      </button>
    </div>
  );
}

export default MyComponent;

Uobičajene zamke koje treba izbjegavati

Alternative React Contextu

Iako je React Context vrijedan alat, nije uvijek najbolje rješenje. Razmotrite ove alternative:

Zaključak

React Context je moćna značajka za dijeljenje podataka između komponenti bez prop drillinga. Razumijevanje kada i kako ga učinkovito koristiti ključno je za izgradnju održivih i performantnih React aplikacija. Slijedeći najbolje prakse navedene u ovom vodiču i izbjegavajući uobičajene zamke, možete iskoristiti React Context za poboljšanje svog koda i stvaranje boljeg korisničkog iskustva. Ne zaboravite procijeniti svoje specifične potrebe i razmotriti alternative prije nego što odlučite hoćete li koristiti Context.

React Context: Sveobuhvatan vodič o tome kada i kako ga koristiti | MLOG