简体   繁体   中英

Redux adding nested value to current state

I have the following state:

{
  list: {
    key1: {
      value: [{a: 'a'}, {b: 'b'}],
      fetching: true
    },
    key2: {
      value: [{c: 'c'}],
      fetching: true
    }
  }
}

I want to provide a new value for some key, and replace current state with this. But I also want the value to be concated with the previous one. So for example with the following action:

key1: {
  value: [{d: 'd'}],
  fetching: false
}

I would get the following state:

{
  list: {
    key1: {
      value: [{a: 'a'}, {b: 'b'}, {d: 'd'}],
      fetching: false
    },
    key2: {
      value: [{c: 'c'}],
      fetching: true
    }
  }
}

How can I do that inside a reducer, so that the case remains immutable? (using ... spread operator, not ImmutableJS ).

EDIT:

Part of the reducer that handles (should to) that:

case "FOO_BAR":
  const key = action.payload.key;
  const newList = {...state.list};
  newList[key] = action.payload.newObject; // {value: ..., fetching: ...}
  return {
    ...state,
    list: newList
  }

It's how I'd like to solve it

case "FOO_BAR":
  const oldList = {...state.list};
  const newKey1Value = action.payload.key.value;
  oldList.key1.value = oldList.key1.value.concat(newKey1Value);
  const newKey1fetching  = action.payload.key.fetching;
  oldList.key1.fetching =  newKey1fetching;
  return {
    ...state,
    list: oldList
  }

I hope it helps you.

You will need to use the spread operator to spread the old values and then spread the newObject[key] value array.

Something like this:

import { get } from 'lodash';

case "FOO_BAR":
  const { key, newObject } = action.payload;
  const newList = {
    ...state.list, 
    [key]: {
      value: [...get(state, 'list[key].value', []), ...newObject[key].value]
      fetching: newObject[key].fetching
    }
  };
  return {
    ...state,
    list: newList
  }

Edit: I added the get utility function from lodash so that if state.list[key] is undefined , it will return an empty array to spread rather than throwing an error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM