post header image

State kezelés Next.js-el II.

Mi is a prop drilling, ismerjük az ellenséget, hogy küzdhessünk ellene

A prop drilling arra a gyakorlatra utal, hogy egy mélyen beágyazott komponenshez adatokat továbbítanak szülő/gyerek - szülő/gyerek komponenseken keresztül.

Ennek a módszernek megvan az a hátránya, hogy a komponensek, amelyen keresztül az adatok kézbesítése kerülnek, csupán csatornaként szolgálnak, hogy az információ eljusson a végső rendeltetési helyére.

A "prop drilling" kifejezés arra a folyamatra utal, amikor arra kényszerítjük ezeket az komponenseket, hogy vegyenek át olyan adatokat amelyek nem szorosan hozzájuk tartoznak, és adják tovább azokat a következő komponensnek, amely továbbküldi a következő komponensnek, és így tovább, amíg el nem éri a célt. Ez a komponens újrafelhasználhatóságát ez súlyosan befolyásolhatja, valamint amennyiben változik ez az adat, így a közvetítő komponensek felesleges rerenderelődésével jár.

Lehetséges megoldások

Most, hogy világossá vált, hogy mit akarunk elérni, milyen problémával szembesülünk, meg kell vizsgálnunk a lehetséges megoldásokat. Az alábbiakban a prop drilling technika alternatíváinak hiányos listája található.

  • React Context API, useState, useReducer (beépített megoldás)
  • Redux
  • React Query
  • Zustand
  • Jotai
  • Mobx

Annak ellenére, hogy nagy rajongói vagyunk a Reduxnak, ha appunk nem túl komplex, javasoljuk a beépített megoldások használatát az állapotkezeléshez.

Amennyiben azonban az app igényel komplexebb state kezelési megoldásokat, akkor mi a külső megoldásokból a Redux segítségét vesszük igénybe.

Cikkünk nem hivatott a Redux részletes bemutatására, ám ismertetjük a Next.js-el való integrálásának lehetőségét.

React Context API vs Redux

  • Context API
  1. Beépített eszköz, amelyet a React magában foglal (csomag méretet nem növel)
  2. Minimális beállítást igényel
  3. Kifejezetten statikus adatokhoz tervezték, amelyeket nem gyakran frissítenek vagy frissítenek
  4. Új kontextusok hozzáadásához a semmiből kell létrehozni minden alkalommal a provider-t
  5. A felhasználói felület logika és az state-kezelési logika ugyanabban az összetevőben találhatók
  6. A hibakeresés nehéz lehet erősen beágyazott komponens struktúra esetén még a Dev Tool használatával is
  • Redux
  1. További csomag telepítése szükséges, ami növeli a végső csomag méretét
  2. A React alkalmazással való integrálása extra beállítást igényel
  3. Statikus és dinamikus adatokkal is remekül működik
  4. Könnyen bővíthető az új adatok/műveletek könnyű hozzáadásának köszönhetően a kezdeti beállítás után
  5. Jobb kódszervezés külön felhasználói felület logikával és állapotkezelési logikával
  6. Hihetetlenül erős Redux Dev Tools a hibakeresés megkönnyítésére

A beépített megoldások: React Context API, useState, useReducer

Fontos megjegyezni, hogy a szolgáltatók (provider-ek) használata kifejezett figyelmet igényel, a kompozícióra mindig legyünk kiemelt tekintettel.

  1. Létrehozhatják az úgynevezett "szolgáltatói poklot" (provider hell), amely feltűnő hasonlóságot mutat a "visszahívási pokol"-hoz (callback).

    // ... imports
    
    const App = () => {
      // ... some code
      return (
        <>
         <ReduxProvider value={store}>
          <ThemeProvider value={theme}>
           <OtherProvider value={otherValue}>
            <OtherOtherProvider value={otherOtherValue}>
             {/** ... other providers*/}
                                    <HellProvider value={hell}>
                                      <HelloWorld />
                                    </HellProvider>
             {/** ... other providers*/}
            </OtherOtherProvider>
           </OtherProvider>
          </ThemeProvider>
         </ReduxProvider>
        </>
      )
    }
    

    Ebben a cikkben arról olvashatunk, hogyan lehet elkerülni a szolgáltató poklot.

  2. Sok fejlesztő össze van zavarodva a Context és a Redux kapcsán, a Context nem helyettesíti a Reduxot, csak egy könnyű súlyú helyettesítője. Van néhány hasonlóság és átfedés, de jelentős különbségek vannak a képességeikben. Különféle eszközökről van szó, különböző dolgokra és célokra használjuk őket. A Context csupán egy eszköz, nem kezel semmit, azt a fejlesztő teszi a useState/useReducer használatával.

  3. Példa egy provider-re - Bár a példában nem használjuk a useReducer-t, ez bonyolultabb statek esetén használatos.

    import {createContext, ReactNode, useContext, useState,} from "react"
    
    type ThemeProviderProps = {
       children: ReactNode
    }
    
    type ThemeContext = {
      isPrimary: boolean
    }
    
    type ThemeDispatchContext = {
       changeTheme: () => void
    }
    
    const ThemeContext = createContext({} as ThemeContext)
    const ThemeDispatchContext = createContext({} as ThemeDispatchContext)
    
    export function useTheme() {
      return useContext(ThemeContext)
    }
    
    export function useDispatchTheme() {
     return useContext(ThemeDispatchContext)
    }
    
    const ThemeProvider = ({children}: ThemeProviderProps) => {
    const [isPrimary, setIsPrimary] = useState<boolean>(true)
    
        const changeTheme = () => {
            setIsPrimary(prevState => !prevState)
        }
    
        return (
            <ThemeDispatchContext.Provider value={{changeTheme}}>
                <ThemeContext.Provider value={{isPrimary}}>
                    <div
                        className={
                            isPrimary 
                               ? "themeable-primary-theme" 
                               : "themeable-secondary-theme"
                            }
                         >
                        {children}
                    </div>
                </ThemeContext.Provider>
            </ThemeDispatchContext.Provider>
        )
    }
    
    export {ThemeProvider}
    

A cikk itt folytatódik.

COPYRIGHT © 1999 - 2024 | SKYLINE-COMPUTER KFT.MINDEN JOG FENNTARTVA