Home > Software design >  Accessing previous state within a useDispatch method
Accessing previous state within a useDispatch method

Time:05-07

How do I access previous state inside the callback function in react? Because once I access data it is always returning an initial state version, since I use useEffect only on mount

const data = useSelector(({ state }) => state.data);
const dispatch = useDispatch();

useEffect(_ => {
    dataService.loadData().then(resp => {
        dispatch({ type: 'SET_DATA', payload: resp.data });
    });
}, []);

const addData = newData => {
    dataService.addData(newData).then(_ => {
        // need the up to date state here for data
        dispatch({ type: 'SET_DATA', payload: [newData, ...data] })
    });
}

return <>
    <button onClick={_ => addData({ name: "new name" })}></button>
    {data.map(elem => <div>{elem.name}</div>)}
</>

CodePudding user response:

I think you are not thinking about Redux correctly. You access the "previous" state in the reducer function. It's actually the current state, but the reducer function is a function of state and action, i.e. (state, action) => nextState.

The reducer function is the place to access the state you are trying to update.

Example:

const initialState = {
  ... other state properties ...
  data: [],
};

const reducer = (state = initialState, action) => {
  switch(action.type) {
    ... other cases ...

    case SET_DATA:
      return {
        ...state,
        data: [action.payload, ...data],
      }

    default:
      return state;
  }
};

The addData handler then just dispatches the action with the newData in the payload.

const addData = newData => {
  dataService.addData(newData)
    .then(_ => {
      dispatch({ type: 'SET_DATA', payload: newData })
    });
};

If you need to differentiate between loading the data and adding to it with regards to how it's handled and updates state, then I suggest using separate action types, SET_DATA and ADD_DATA for example.

  • Related