In a React / Redux reducer, how can I invariably update a string in a nested array?

My store is as follows:

{
  name: "john",
  foo: {},
    arr: [
      {
        id:101,
        desc:'comment'
      },
      { 
        id:101,
        desc:'comment2'
      }
    ]
}

My text area looks like

<textarea
  id={arr.id} //"101"
  name={`tesc:`}
  value={this.props.store.desc}
  onChange={this.props.onChng}
/>

My action

export const onChng = (desc) => ({
  type: Constants.SET_DESC,
  payload: {
    desc
  }
});

My gear

case Constants.SET_DESC:
  return update(state, {
    store: {
      streams: {
        desc: { $set: action.payload.desc }
      } 
    }
});

It only works if arry is an object, I had to make changes to the stream in the array, and I am confused about how I can update the array, and also how to get the correct value from the repository.

+4
source share
3 answers

To update the array, I used the immutability assistant and do something like this to your reducer

 let store = {"state" : {
"data": [{
    "subset": [{
        "id": 1
    }, {
        "id": 2
    }]
}, {
    "subset": [{
        "id": 10
    }, {
        "id": 11
    }, {
        "id": 12
    }]
}]
}}

case Constants.SET_DESC:
  return update(store, {
  "state" : {
  "data": {
      [action.indexToUpdate]: {
        "subset": {
             $set: action.payload.desc
        }
      }
  }
 }
  })
  });
0
source

, redux, . http://redux.js.org/docs/recipes/StructuringReducers.html

- -

{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}

function updateObject(oldObject, newValues) {
    // Encapsulate the idea of passing a new object as the first parameter
    // to Object.assign to ensure we correctly copy data instead of mutating
    return Object.assign({}, oldObject, newValues);
}

function updateItemInArray(array, itemId, updateItemCallback) {
    const updatedItems = array.map(item => {
        if(item.id !== itemId) {
            // Since we only want to update one item, preserve all others as they are now
            return item;
        }

        // Use the provided callback to create an updated item
        const updatedItem = updateItemCallback(item);
        return updatedItem;
    });

    return updatedItems;
}

function appReducer(state = initialState, action) {
    switch(action.type) {
        case 'EDIT_TODO' : {
            const newTodos = updateItemInArray(state.todos, action.id, todo => {
                return updateObject(todo, {text : action.text});
            });

            return updateObject(state, {todos : newTodos});
        } 
        default : return state;
    }
}
+2

If you need to update an element in an array in your store, you need to copy the array and clone the corresponding element to apply your changes.

So, in the first step, your action should contain either an already cloned (and modified) object, or an object identifier and mutable properties.

Here is an example:

export class MyActions {
    static readonly UPDATE_ITEM = 'My.Action.UPDATE_ITEM';

    static updateItem(id: string, changedValues: any) {
        return { type: MyActions.UPDATE_ITEM, payload: { id, changedValues } };
    }
}

export const myReducer: Reducer<IAppState> = (state: IAppState = initialState, action: AnyAction): IAppState => {
    switch (action.type) {
        case MyActions.UPDATE_ITEM:
            return { ...state, items: merge(state.items, action.payload) };

        default:
            return state;
    }
}

const merge = (array, change) => {
    // check if an item with the id already exists
    const index = array.findIndex(item => item.id === change.id);
    // copy the source array
    array = [...array];

    if(index >= 0) {
        // clone and change the existing item
        const existingItem = array[index];
        array[index] = { ...existingItem, ...change.changedValues };
    } else {
        // add a new item to the array
        array.push = { id: change.id, ...change.changedValues };
    }

    return array;
}
+1
source

Source: https://habr.com/ru/post/1684639/


All Articles