Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update an array within object with useReducer

I am trying to update a state object. One of the items is a key whose value is an array of strings.

I've been able to update the state, but it does not rerender.

const initialState = {
  showUpload: false,
  listItems: parentDirs,
  uploadPath: [],
  fileList: null
};

const reducer = (state, action) => {
  switch (action.type) {
    case "updateListItems":
      return { ...state, listItems: action.payload };
    case "updatePath":
      return {
        ...state,
        uploadPath: [...state.uploadPath, action.payload]
      };
    default:
      return state;
  }
};

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

const pathFormat = state.uploadPath.join('/')

return (
 <p>{pathFormat}</p>
)

The expected behavior would be that updating the array within the state object would trigger a rerender.

like image 737
huge-iguana Avatar asked Dec 15 '25 18:12

huge-iguana


1 Answers

Not entirely sure what lives inside that array, but here's an example that might help.

The thing you need is an identifier to target. Lets say you have the following:

state = {
cats: [
 {
  name: 'cat1',
  id: 1
 },
  name: 'cat2',
  id: 2
 }
],
// ... rest of state

}

To override cat 2, you'd do something like:

//           action.type           action.payload
dispatch({ type: 'updateCats', payload: {id: 2, name: 'cat3' }})

// ... and your reducer's switch returns:
case 'updateCats':
  return {
    ...state,
    cats: [...state.cats.filter( cat => id !== payload.id), action.payload]
}

You need to rebuild the array by removing the old item and adding it again. How you do this is up to you. You can either slice & splice, or if order isn't important the filter method used in the example should work.

like image 193
Mark Michon Avatar answered Dec 18 '25 13:12

Mark Michon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!