State Management

Essential React

React Context

How to handle application wide state

Motivation

Prevent Prop Drilling

Prop Drilling

React Context API

Step by Step

Context must be created using
const YourContext = createContext<ValueType>(…)

The parameter is the default value of the context.

Provide context in an ancestor component using

              
                
              
            

Consume within any descendant component using
const value = useContext(YourContext)

What to put in contexts?

Any JavaScript object can be the value of a context.

  • A JSON object
  • An object having fields being functions

Example Use Cases

  • Theme Info
  • Auth Context
  • Language Info

Exercise

  • Enhance the profile component by prefilling the default form values
  • Display the username globally (e.g. in the header)
  • Hint 1: Provide the context in the App.tsx
  • Hint 2: The value of the context can rely on values of other Hooks

Default values can be provided to the form like this:

                    
                

Solution

UserContext.ts

                    
                

Solution continued

Profile.tsx

Solution continued

App.tsx

                    
                

Solution continued

Layout.tsx

                    
                

How to handle more complex states?

It depends.

Flux / Redux Pattern

Cycle

  1. Creating an action object
  2. Dispatch the action
  3. Reducer will process the action and create a new store based on the previous store and the action itself
  4. View rerenders with new store

React provides built-in Hooks for flux-based state management without having to use Redux .

useReducer Hook

Takes a reducer function and an initialState

Returns an array with two values, the current state and a dispatch function

                    
                        const [state, dispatch] = useReducer(reducer, initialState);
                    
                

Reducer function

Is called with two parameters

  1. The current state
  2. The action the reducer has been called with
                    
                        function reducer(state: State, action: Action) {
                          switch (action.type) {
                            case 'increment':
                              return {count: state.count + 1};
                            case 'decrement':
                              return {count: state.count - 1};
                            default:
                              throw new Error("unknown action type");
                          }
                        }
                    
                
Never manipulate the existing state reference. Always return a new state object!

Type Example

                    
                        type State = {
                            count: number;
                        }
                        type Action = { type: 'increment' | 'decrement' }
                    
                

Applying reducers

  • Can be standalone within a single component
  • Can be used together with useContext

useReducer Exercise

  • Add a pokemon visit counter to your application
  • Count how many pokemon the user has seen
  • Display the count somewhere in your app
  • Add a reset button to reset the counter

Stretch Goal

Don't count multiple visits to the same pokemon.

Solution

usePokeVisit.ts types

                    
                

usePokeVisit.ts reducer function & initial state

usePokeVisit.ts reducer Hook

                    
                

using usePokeVisit.ts

                  
              

Dispatching Reducer Actions

Stretch Goal Solution

                    
                

Overview over more extensive State Management

A rough overview of the different solutions available

Redux / Zustand (flux-based)

Provide additional features that useReducer does not:

  • Middlewares - code to execute after action dispatching and before reducer (e.g. to start data fetching, logging)
  • Selectors - derive aggregations from store

Valtio / MobX (proxy-based)

Permit direct state mutation

Proxy

Recoil / Jotai (atom-based)

Primary focus on state and selectors

As of 2022 recoil is still experimental

XState

Finite state machines and state charts

Rule of Thumb

Prefer simple solutions for state management

Recap

We learned…

  • Context API
  • useReducer
  • External state management solutions

Questions?