Alejandro Alejandro - 3 months ago 18
React JSX Question

Update List via Redux's Reducer

I am making a small recipe list for learning purposes on React (since I am new to it).

I was able to figure out how to ADD and DELETE recipes from the list. However I am hard time how to EDIT a recipe from the list (App's state).

Following from Redux's document:


Because we want to update a specific item in the array without
resorting to mutations, we have to create a new array with the same
items except the item at the index.


I am having trouble how select the specific item in the array when the array that is selected itself is modified.

Here is my Actions file:

src/actions

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;
}


I suspect I need to add an id in the actions to differentiate it from the array list?

Answer

You should add an id to objects in 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'] },
];

Then update your recipe:

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

You should use === instead of == on if condition only if you are sure that recipe.id and action.payload.id are both Integer.

Comments