首页 > 解决方案 > Redux reducer - modifying array with forEach

问题描述

Have a small problem with fetching and based on response updating an array inside my state in Redux.

First I have done the whole array update with forEach in actions (based on my initial state object) and sent it ready to reducer, it worked. Simple.

But then read tutorials that modifying should be done only in the reducer, and that action should only deal with getting the response. So I have tried doing it this way, two ways, both failed.

The payload i have dispatched to reducer in both cases was just the ready response i have got.

Can someone please enlighten me what went wrong and what's the correct way to do this in reducer?

Both approaches didn't work:

export const handleMusicCards = (state = musicState, action = {}) => { switch (action.type) {

case REQUEST_MUSIC_SUCCESS:
  return Object.assign({}, state, {
    musicStateItemList: state.musicStateItemList
      .forEach((el, i) => {
        el.track = action.payload.message.body.track_list[i].track.track_name;
        el.album = action.payload.body.track_list[i].track.album_name;
        el.artist = action.payload.body.track_list[i].track.artist_name;
        el.id = action.payload.body.track_list[i].track.track_id;
        el.favClicked = false;
        el.addedToFav = false;
      }),
    isLoading: false
  });

} }

export const handleMusicCards = (state = musicState, action = {}) => { switch (action.type) {

case REQUEST_MUSIC_SUCCESS:
  return Object.assign({}, state, {
    musicStateItemList: state.musicStateItemList
      .forEach((el, i) => {
        return {
          ...el,
          track: action.payload.message.body.track_list[i].track.track_name,
          album: action.payload.message.body.track_list[i].track.album_name,
          artist: action.payload.message.body.track_list[i].track.artist_name,
          id: action.payload.message.body.track_list[i].track.track_id,
          favClicked: false,
          addedToFav: false,
        }
      }),
    isLoading: false
  });

} }

标签: reactjsredux

解决方案


I am not sure after reading it where the failure is occurring. A little more about redux conventions.

The action objects are only to describe what changes should be made to the state. The reducer is where the state should actually be changed. In redux, you never want to modify the state object, instead you want to copy it and return a new object with the changes, as described by the action objects.

So you might have a reducer case that looks something like this...

const reducer = (state, action) => {
    switch (action.type) {
        case NEW_RECORD_SUBMIT :
            return {
                ...state,
                newRecordStatus: action.status,
            };
    default :
          return state;
  }
};

推荐阅读