Обновить список через Redux Reducer

Я составляю небольшой список рецептов для обучения React (поскольку я новичок в этом).

Я смог понять, как ДОБАВЛЯТЬ и УДАЛЯТЬ рецепты из списка. Однако мне сложно ИЗМЕНИТЬ рецепт из списка (состояние приложения).

Следуя из документа Redux:

Поскольку мы хотим обновить определенный элемент в массиве, не прибегая к мутациям, мы должны создать новый массив с такими же элементами, кроме элемента в индексе.

У меня возникли проблемы с выбором конкретного элемента в массиве при изменении самого выбранного массива.

Вот мой файл действий:

источник / действия

export const RECIPE_ADD = 'RECIPE_ADD';
export const RECIPE_EDIT = 'RECIPE_EDIT';
export const RECIPE_DELETE = 'RECIPE_DELETE';
export function addRecipe(recipe) {
  return {
    type: RECIPE_ADD,
    payload: recipe
  }
}
export function editRecipe(recipe) {
  return {
    type: RECIPE_EDIT,
    payload: recipe
  }
}
export function deleteRecipe(recipe) {
  return {
    type: RECIPE_DELETE,
    payload: recipe
  }
}

src / reducers / reducer_recipe

import { RECIPE_ADD } from '../actions/index';
import { RECIPE_DELETE } from '../actions/index';
import { RECIPE_EDIT } from '../actions/index'

const defaultList = [
  { recipe: 'Pizza', ingredients: ['tomato-sauce','cheese','peperoni'] },
  { recipe: 'Pie', ingredients: ['dough','cherry'] },
  { recipe: 'Curry', ingredients: ['rice','sauce','carrots'] },
];

export default function(state = defaultList, action){
  switch (action.type) {
    case RECIPE_ADD:
      return [
        { recipe: action.payload[0], ingredients: action.payload[1] },
        ...state
      ];
    case RECIPE_DELETE:
    let index = state.map(x => x.recipe).indexOf(action.payload.recipe)
      return (
        state.slice(0,index).concat(state.slice(index + 1))
      )
    case RECIPE_EDIT:
    console.log(action.payload)
    // action.payload is the updated selected recipe
      return (
        state
      )
  }
  return state;
}

Я подозреваю, что мне нужно добавить идентификатор в действия, чтобы отличить его от списка массивов?


person Alejandro    schedule 29.08.2016    source источник


Ответы (2)


Вы должны добавить идентификатор к объектам в defaultList:

const defaultList = [
  { id: 1, recipe: 'Pizza', ingredients: ['tomato-sauce','cheese','peperoni'] },
  { id: 2, recipe: 'Pie', ingredients: ['dough','cherry'] },
  { id: 3, recipe: 'Curry', ingredients: ['rice','sauce','carrots'] },
];

Затем обновите свой рецепт:

    case RECIPE_EDIT:
      return state.map((recipe)=> {
        if( recipe.id == action.payload.id ) {
          return action.payload
        } else {
          return recipe;
        }
      });

Вы должны использовать === вместо == в условии if, только если вы уверены, что recipe.id и action.payload.id оба являются целыми числами.

person bnsd55    schedule 30.08.2016
comment
Замечательно, я взял вашу идею и реализовал в своем файле действий: export function addRecipe(recipe) { const id = shortid.generate(); return { type: RECIPE_ADD, payload: recipe, id: shortid.generate() } } Это помогло правильно выбрать выбранный рецепт. - person Alejandro; 30.08.2016

Может как то так заработает:

import { RECIPE_ADD } from '../actions/index';
import { RECIPE_DELETE } from '../actions/index';
import { RECIPE_EDIT } from '../actions/index'

const defaultList = [
  { recipe: 'Pizza', ingredients: ['tomato-sauce','cheese','peperoni'] },
  { recipe: 'Pie', ingredients: ['dough','cherry'] },
  { recipe: 'Curry', ingredients: ['rice','sauce','carrots'] },
];

export default function(state = defaultList, action){
  switch (action.type) {
    case RECIPE_ADD:
      return [
        { recipe: action.payload[0], ingredients: action.payload[1] },
        ...state
      ];
    case RECIPE_DELETE:
      let index = state.map(x => x.recipe).indexOf(action.payload.recipe)
        return (
          state.slice(0,index).concat(state.slice(index + 1))
        )
    case RECIPE_EDIT:
      return state.map((recipe)=> {
        if( recipe.name === action.payload.name ) {
          return action.payload
        } else {
          return recipe;
        }
        return recipe;
      });
  }
  return state;
}
person Sotiris    schedule 29.08.2016
comment
Я забыл упомянуть, что пользователь может редактировать рецепт и / или сами ингредиенты. Так что это не сработает - person Alejandro; 30.08.2016