Удалить один элемент в массиве ReactJS (React Hooks и Redux)
Я создаю приложение-рецепт с использованием стека MERN.
Проблема, на которой я застрял, - это попытка удалить ингредиент, найденный в массиве, внутри объекта рецепта. Мой объект рецепта выглядит так:
Рядом с каждым ингредиентом есть крестик, который позволяет щелкнуть по нему, чтобы удалить.
<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: Cannot read property 'map' of undefined".
Что-то мне здесь не хватает? Я работаю над этим приложением последние пару месяцев и застрял на этом конкретном моменте. Я подумал, что лучше будет использовать Redux, так как я смог удалить целый рецепт с помощью редуктора:
case DELETE_RECIPE:
return {
...state,
recipes: state.recipes.filter(recipe => recipe._id !== action.payload),
loading: false
};
но как я могу выбрать один конкретный ингредиент?
Любые предложения будут ценны.
1 ответ
Я добавил примечания к вашим проблемам с кодом)
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)
возвращает отфильтрованные ингредиенты вместо добавок Ингредиенты с полем отфильтрованных ингредиентов
Как это должно быть
const addIngredient = e => {
e.preventDefault();
if (query === '') return;
setIngredients({
...addIngredients,
ingredients: [
...addIngredients,
query
]
});
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: results
});
};