Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux - How to add entry to array in reducer

Tags:

I stuck with this bit and I can't progress - I guess solution is simple but I can't figure out. I'm trying to add entry in reducer so data in in would look something this:

state = {
  entryId: {
    entryName: ["something", "something2", "something3" /* and so on... */]
  }
};

So far this is the closest I get, but, instead of adding new unique entry, it is replacing the one that is stored already. Also I need to be able to add this item to empty state where entryId, entryName doesn't exist yet to avoid error:

switch(type) {
  case ADD_ENTRY:
    return {
      ...state,
      [entryId]: {
        ...state[entryId],
        [entryName]: {
          [uniqueEntry]: true
        }
      }
    };
}

Any idea what I'm doing wrong?

like image 651
eloleon Avatar asked Jun 20 '16 22:06

eloleon


People also ask

How do I add an element to array in reducer of react Redux?

Simply set the array to the output of concat() and return the state. Save this answer.

How do you update a reducer?

The only way to update a state inside a store is to dispatch an action and define a reducer function to perform tasks based on the given actions. Once dispatched, the action goes inside the reducer functions which performs the tasks and return the updated state to the store.

How do I store data in Redux Reducer?

Detailed Explanation: Adding Redux to a React Project Add the @reduxjs/toolkit and react-redux packages. Create a Redux store using RTK's configureStore API, and pass in at least one reducer function. Import the Redux store into your application's entry point file (such as src/index.js )

Can we update state in reducer?

The state is updated and managed by reducers. Reducers always have to return something even if it's null ; they should never return undefined . If a reducer's state is an object, you must always return a new object instead of editing the object in place.


1 Answers

If you're trying to add an element to the end of the entryName array you should be doing:

return {
  ...state,
  [entryId]: {
    ...state[entryId],
    [entryName]: [
      ...state[entryId][entryName],
      uniqueEntry
    ]
  }
};

ES6 spread with arrays works like this:

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const eight = 8;

const newArray = ['stuff', ...array1, 'things', ...array2, ...[7, eight], 9];
console.log(newArray); // ["stuff", 1, 2, 3, "things", 4, 5, 6, 7, 8, 9]

Check out this gist which has an example of something very similar to what you're doing.

I found this set of examples extremely helpful as well. A lot of great stuff in here:

https://github.com/sebmarkbage/ecmascript-rest-spread

Update:

If entryName is initialized to undefined like you say in your comment, you could do this:

return {
  ...state,
  [entryId]: {
    ...state[entryId],
    [entryName]: [
      ...state[entryId][entryName] || [],
      uniqueEntry
    ]
  }
};

I think this is a pretty great example of how painful it can be working with React/redux using a heavily nested data structure. FWIW, it's been recommended to me many times to flatten your state as much as possible.

like image 143
jaybee Avatar answered Sep 21 '22 10:09

jaybee