React Hooks – the Sequel – Context & the Reducer

Deel 2 van de React hooks serie en deze week gaan we het hebben over useContext en useReducer. De useContext hook zorgt ervoor dat je props niet eindeloos door hoeft te geven van boven naar beneden maar dat je child componenten er direct gebruik van kunnen maken. En met de useReducer hook heb je een vervanger voor useState die beter om kan gaan met complexe state logica.
updated: Jan 28, 2021 at 5:59PM | published: Jan 28, 2021
Vorige week hebben we de wondere wereld van React hooks geintroduceerd. Daar hebben we uitgelegd wat zijn nou precies hooke en waarom zijn ze ontwikkeld. Ook hebben we je voorbeelden gegeven van de meest gebruikte hook de useState hook om je state te declaren en updaten en de useEffect hook om effect toe te voegen deze doen heel veel denken aan de lifecycle methods. Meer lezen daarover? Klik op het artikel hier onder.
Deze week gaan we het hebben over de useContext en de useReducer hook. De useContext, zal naast de useEffect en de useState hook, de hook zijn die je het meest gaat gebruiken daarom hoort die ook nog bij de Basic hooks. De andere is erg nuttig als je complexe applicaties met ingewikkelde state logica gaat bouwen.

useContext

De useContext hook zorgt ervoor dat je gebruik kan maken van de context api in functional components. In een standaard React applicatie wordt data van parent naar child component doorgegeven. Maar dit kan al snel heel verwarrend worden als je een diep genestelde structuur hebt en je moet iets doorgeven van je hoofdcomponent helemaal door naar het onderste component. Context zorgt ervoor dat je een manier hebt om data van waar dan ook in je applicatie door kan geven naar een ander deel in je applicatie zonder dat je de data door je hele boom structuur moet doorgeven

Hoe context werkt is je maakt een nieuw context object met React.createContext dit geeft een provider en een consumer component terug. Deze kunnen we ‘destructuren’ uit het object.

JS

import React from ‘react’;

const mijnContext = React.createContext();
cont { Provider, Consumer } = mijnContext;

Het Provider component is hetgene wat zorgt dat je state toegangkelijk wordt voor elk child component. Je wrapt je parent component met het Provider component die ontvangt een value prop en daarop geef je de waarde mee die je toegangkelijk wil maken. Je Consumer component zoals de naam doet vermoeden ‘consumed’ de waarde voor gebruik in het child component waar je het in wil gebruiken.

JS

 <Provider value=’Ajax’>
        {children}
</Provider>

<Consumer>
        { value => <div>Wat is de beste voetbalclub? { value } </div>}
</Consumer>

Zoals je ziet geeft dit nogal wat extra Component nesting omdat je overal waar je toegang wil hebben tot de waardes van de provider moet je je content wrappen in een Consumer component. Gelukkig heb je hier geen last van met de useContext hook. De useContext hook zorgt ervoor dat als je toegang wil krijgen tot de value van provider het enige wat je hoeft te doen is het createContext object meegeven aan useContext en je hebt toegang tot de waardes die je in je Provider hebt opgegeven. Hieronder kan je een voorbeeld zien hoe dit eruit ziet.

JS

[VoetbalContext.js]

const clubsEredivisie = {
   nummer1: “Ajax”,
   nummer2: “PSV”,
   nummer3: “Vitesse”
};

export const VoetbalContext = React.createContext(clubsEredivisie.nummer1);

JS

[index.js]

import React from ‘react’;
import { VoetbalContext } from “./VoetbalContext”;

const App = () => {
  return (
    <VoetbalContext.Provider value={clubsEredivisie}>
      <Home />
    </VoetbalContext.Provider>
  );
}

export default App

JS

[MyPersonalComponent.js]

import React, { useContext } from “react”;
import VoetbalContext from ‘./VoetbalContext’;

const MyPersonalComponent = () => {
  const clubs = useContext(VoetbalContext);

  return(
        <div>
                <div>De nummer 1 club van de eredivisie is: {clubs.nummer1}</div>
                <div>De nummer 2 club van de eredivisie is: {clubs.nummer2}</div>
                <div>De nummer 3 club van de eredivisie is: {clubs.nummer3}</div>
        </div>
  )
};

export default MyPersonalComponent

In het bovenste bestand geven de waardes die we in het createContext object zetten. In ons App component geven we de Provider de waardes mee en als laatste in ons MyPersonalComponent gebruiken we de useContext hook. Het maakt voor useContext niet uit hoe diep genesteld dit component zijn dus het kan een kind van een kind van een kind zijn. Dit component gebruikt de useContext hook om de waardes uit het VoetbalContext object te halen.

useReducer

De volgende hook waar ik het over ga hebben is de useReducer hook deze kan in samenwerking met useContext hook een soort van store creëeren waar je globaal al je state bewaart gelijk aan Redux. Redux is een state management oplossing die kan gebruikt worden in React applicaties om overzichtelijk je state te beheren. Dit is wenselijk omdat zodra je applicatie groeit je hoeveelheid state meegroeit totdat je op een gegeven moment door de bomen de state niet meer kan zien. In een later artikel zal ik meer vertellen over Redux.

De useReducer hook kan als alternatief voor de useState hook gebruikt worden. Het is zelfs aan te raden om useReducer te gebruike als je complexe state logica hebt of als je volgende state afhangt van de vorige. De useReducer ontvangt 2 waardes als argumenten een reducer functie en de initiele state. De reducer functie geeft aan de hand van de action type de nieuwe state terug (state, action) => newstate hieronder een voorbeeld van de reducer hook.

JS

import React, { useReducer } from “react”;

const initialState = {
        ajax: 10,
        psv: 4,
        vitesse: 6,
        feyenoord: 8
};

const reducer = (state, action) => {

  switch (action.type) {
    case ‘ajax’:
      return {…state, ajax: state.ajax + 1};
    case ‘psv’:
      return {…state, psv: state.psv + 1};
    case ‘vitesse’:
      return {…state, vitesse: state.vitesse + 1};
    case ‘feyenoord’:
          return {…state, feyenoord: state.feyenoord + 1};
    default:
      throw new Error();
  }
}

const VoteWidget = () => {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
        <h1>Stem op je favoriete club!</h1>
        Ajax: {state.ajax}
        <button onClick={() => dispatch({type: ‘ajax’})}>Ajax</button>
        PSV: {state.psv}
        <button onClick={() => dispatch({type: ‘psv’})}>PSV</button>
        Vitesse: {state.vitesse}
        <button onClick={() => dispatch({type: ‘vitesse’})}>Vitesse</button>
        Feyenoord: {state.feyenoord}
        <button onClick={() => dispatch({type: ‘feyenoord’})}>Feyenoord</button>
    </div>
  );
}

export default VoteWidget

Dit voorbeeld geeft een hele simpele stem widget weer in onze initialState hebben we 4 state variabelen waar we onze begin stemmen in zetten. Dan komt onze reducer functie die onze state update met 1 stem aan de hand van de action type die gedispatched wordt de verschillende type clubs dat zijn onze action types. En als laatste ons component waar de useReducer hook wordt gebruikt, in onze useReducer hook geven we de reducer functie en de intitial state mee als argumenten. Vervolgens krijgen we ons stukje JSX waar we de state waardes laten zien en met een button erbij zodat we er op kunnen stemmen dit doen we met een dispatch die een type meekrijgt die correspondeert met een case uit onze reducer functie.

Dat was het weer voor deze week zoals je ziet weer een lang artikel voor maar 2 hooks daarom ga ik het hier bij laten en vertel ik in een volgend artikel over de laatste paar hooks. Heb je hulp nodig met een complex React project, onze React specialisten staan altijd klaar om u te helpen. Tot volgende week!


Deel 4 van de React Hooks serie useMemo & useCallback

Deel 4 van de React Hooks serie useMemo & useCallback

Deel 4 van de ReactHooks serie! We gaan het hebben over useCallback en over useMemo. Met deze hooks kunnen we waardes of callback memoizen dit kan nuttig zijn bij zware operaties of om te zorgen dat bepaalde componenten niet altijd mee rerenderen. Zeker omdat bij kleine applicatie het vaak efficienter is om niet te optimaliseren dan wel.

Lees meer
Redux de Intro!

Redux de Intro!

Deze week een korte introductie van de 4 basisbegrippen die je nodig hebt om Redux te begrijpen. We gaan kort uitleggen hoe state wordt aangepast in een Redux Store met behulp van Reducers en Actions. En we vertellen wat al deze begrippen doen en hoe ze werken in een Redux applicatie.

Lees meer

Software ontwikkeling op maat

Hoe werkt het?

Wat wonderen doet voor het ene bedrijf kan zinloos zijn voor een ander bedrijf. Daarom hebben we oplossingen op maat die het unieke karakter van jouw bedrijf respecteren. We werken in een positieve spiraal van testen, monitoren en verzamelen gegevens om precies te weten te komen wat voor jou werkt en wat niet. Het is onze ‘whole package’-mindset, een aandacht voor details die ons in staat stelt om elke keer jouw prestatiedoelstellingen te bereiken. Dus ontspan en geniet van de rit!