Мой магазин выглядит так,

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

Моя текстовая область выглядит так

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

Мое действие

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

Мой редуктор

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

Это работает, только если массив является объектом, мне пришлось вносить изменения в поток в массив, и я запутался, как я могу обновить массив, а также как получить правильное значение из хранилища.

5
Zena Mesfin 29 Авг 2017 в 05:38

3 ответа

Лучший ответ

Чтобы обновить массив, я бы использовал помощник по постоянству и сделал что-то вроде это - твоему редуктору

 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
nolawi 29 Авг 2017 в 06:18

Следующий пример, взятый из документации излишка, может помочь вам в случае использования, как обновить элементы в массиве. Подробнее об этом вы можете прочитать здесь 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
Arun Redhu 29 Авг 2017 в 04:44

Если вам нужно обновить элемент в массиве в вашем магазине, вы должны скопировать массив и клонировать соответствующий элемент, чтобы применить ваши изменения.

Таким образом, на первом этапе ваше действие должно содержать либо уже клонированный (и измененный) объект, либо идентификатор объекта и свойства, которые нужно изменить.

Вот грубый пример:

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
Oliver 29 Авг 2017 в 06:46