删除数组ReactJS中的一项React Hooks和Redux

问题描述

我正在使用MERN堆栈创建食谱应用程序。

我遇到的问题是试图删除配方对象内部数组中的成分。我的食谱对象看起来像这样:

MongoDB Recipe Object

每种成分旁边都有一个叉,允许您单击以将其删除

<div>
      <ol className='pad5px20px'>
        {addIngredients.ingredients.map(data => (
          <div className='ingredient-item padTB5px' key={data}>
            <li>{data}</li>
            <span onClick={() => removeIngredient(data)}>
              <i className='fas fa-trash'></i>
            </span>{' '}
                  
          </div>
        ))}
      </ol>
    </div>

addIngredients和removeIngredient函数如下所示:

  const addIngredient = e => {
e.preventDefault();

if (query === '') return;

addIngredients.ingredients.push(query);
setIngredients(addIngredients);

setRecipe(prevstate => ({
  ...prevstate,ingredients: [
    ...prevstate.ingredients,{ id: Date.Now(),ingredient: query }
  ]
}));
};

  const removeIngredient = data => {
const results = addIngredients.ingredients.filter(
  e => e.ingredients !== data
);
setIngredients(
  addIngredients.ingredients.filter(e => e.ingredients !== data)
);
};

每次从列表中删除成分时,都会收到一条错误消息,指出“ TypeError:无法读取未定义的属性'map'”。

在这里缺少什么吗?在过去的几个月中,我一直在使用此应用程序,但在这一特定方面我一直处于困境。我认为更好的方法是使用Redux,因为我已经可以使用reducer删除整个配方:

    case DELETE_RECIPE:
  return {
    ...state,recipes: state.recipes.filter(recipe => recipe._id !== action.payload),loading: false
  };

但是我如何才能针对一种特定成分?

任何建议将不胜感激。

解决方法

我为您的代码问题添加了注释)

  const addIngredient = e => {
      e.preventDefault();

      if (query === '') return;

     ***STATE MUTATION***
      addIngredients.ingredients.push(query);
     setIngredients(addIngredients);

    setRecipe(prevState => ({
       ...prevState,ingredients: [
       ...prevState.ingredients,{ id: Date.now(),ingredient: query }
  ]
}));
};

  const removeIngredient = data => {
    const results = addIngredients.ingredients.filter(
       e => e.ingredients !== data
    );
    ***You're adding ingredients object instead of addIngredients as you used in addIngredient method***
   setIngredients(
     addIngredients.ingredients.filter(e => e.ingredients !== data)
   );
};

addIngredients.ingredients.filter(e => e.ingredients !== data)返回过滤的成分,而不是带有过滤成分的addIngredients字段

应该如何

  const addIngredient = e => {
      e.preventDefault();

      if (query === '') return;

     setIngredients({
       ...addIngredients,ingredients: [
          ...addIngredients,query
       ]
     });

    setRecipe(prevState => ({
       ...prevState,ingredient: query }
  ]
}));
};

  const removeIngredient = data => {
    const results = addIngredients.ingredients.filter(
       e => e.ingredients !== data
    );

   setIngredients(
    {
       ...addIngredients,ingredients: results
  });
};