Home > Mobile >  Updater function with useReducer?
Updater function with useReducer?

Time:08-24

In react, with useState, I can pass it an updater function to get the current state within the same function. Currently I update a state multiple times within the same function.

Is that possible with a reducer dispatch with useReducer?

Thanks.

const someFunc = () => {
// some other computation
const result = someOtherFunc();
setState((state)=>{
// do something with current state
return {...state, result} 
})

const result2 = someOtherFunc2();
setState((state)=>{
// do something with current state
return {...state, result2} 
})
}

CodePudding user response:

Yes it is. You can do this by grouping all your states in like an initialState variable:

import  { useReducer, useEffect } from 'react';

const SampleComponent = () => {
    const reducer = (state, action) => ({...state, ...action})
    const initialState = {
        someName: '',
        someCounter: 0,
        isLoading: false
    }

    const [{
        someName, someCounter, isLoading
    }, dispatch ] = useReducer(reducer, initialState )

    useEffect(() => {
       dispatch({ isLoading: true }

       const res = await fetch('https://someapi')
       const json = await res.json()

       if (json) {
           dispatch({ 
               someName: json.someNameValue, 
               someCounter: someCounter   json.someCounterValue, 
               isLoading: false 
           })
       }
    }, [])

    return (
       <>
           <h1>{someName}</h1>
           <span>{someCounter}</span>
       </>
    )

}

There maybe other ways to do this, but the way works best for me is to:

  1. Declare a reducer: const reducer = (state, action) => ({...state, action})

  2. Declare all states group in an object state: const initialState = { someState: '' }

  3. Use useReducer with the state variables and dispatch encapsulated with it: const [{ someState }, dispatch ] = useReducer(reducer, initialState)

  4. Use dispatch() method to set new values of states: dispatch({ someState: newValue }) where newValue is any value you want to assign to someState.

CodePudding user response:

Yes it is possible. Whatever that can be done with useState can also be done by useReducer. It is the context that makes us decide on which to use.

Suppose I just want to update my loading state, then useState is enough

const [isLoading, setIsLoading] = useState(true);

But let's suppose I have a input form, if I decide to useState, then it will be kind of like this

const [name, setName] = useState('')
const [age, setAge] = useState(0);
const [address, setAddress] = useState('');

instead of using all these useState, I could directly using useReducer for this specific application

const initialFormValues = {
  name: '',
  age: 0,
  address: '',
};

const reducer = (state, action) =>{
  switch(action.type) {
    case "NAME": return { ...state, name: action.value};
    case "AGE": return { ...state, age: action.value};
    case "ADDRESS": return { ...state, address: action.value};
  }
}

const [formValues, dispatch] = useReducer(reducer, initialFormValues);

Now whenever you want to update your input fields in the form, just use dispatch.

Both can do the task. Depending upon the use-case, we can choose the more appropriate one.

  • Related