Please help guys. So I've started to learn about useReducer and useContext and I'm stuck at deleting an object. I've tried to log the result in the console and it prints the expected array that I want. However, when I return the array from the reducer, and whenever I delete an object, it clears the array and the button is left. So I've got this 2 js files below.
useContext & useReducer
import { createContext, useReducer } from "react";
const initialState = {
items: [],
};
const reducer = (state, action) => {
switch (action.type) {
case "ADD_ITEM":
return { ...state, items: [action.payload, ...state.items] };
case "DEL_ITEM":
return {
...state,
items: [state.items.filter((item) => item.id !== action.payload)],
};
default:
return state;
}
};
export const ItemContext = createContext(initialState);
export const ItemProvider = (props) => {
const [state, dispatch] = useReducer(reducer, initialState);
const addItem = (item) => {
dispatch({ type: "ADD_ITEM", payload: item });
};
const delItem = (id) => {
dispatch({ type: "DEL_ITEM", payload: id });
};
return (
<ItemContext.Provider value={{ items: state.items, addItem, delItem }}>
{props.children}
</ItemContext.Provider>
);
};
import React, { useContext, useState } from "react";
import { ItemContext } from "../Context/ItemContext";
const Test2 = () => {
const { items } = useContext(ItemContext);
const { addItem } = useContext(ItemContext);
const { delItem } = useContext(ItemContext);
const [name, setName] = useState("");
const [price, setPrice] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
const newItem = {
id: items.length + 1,
name: name,
price: price,
};
addItem(newItem);
setName("");
setPrice("");
console.log(newItem);
};
const handleDelete = (id) => {
delItem(id);
};
return (
<div>
<div>
<form>
<label>Product Name:</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<label>Product Price:</label>
<input
type="text"
value={price}
onChange={(e) => setPrice(e.target.value)}
/>
<button onClick={handleSubmit}>Submit</button>
</form>
</div>
<div>
{items.map((item) => (
<div key={item.id}>
<li>
<p>{item.name}</p>
<p>{item.price}</p>
</li>
<button onClick={() => handleDelete(item.id)}>X</button>
</div>
))}
</div>
</div>
);
};
export default Test2;
The Array.filter()
already returns a new array, so when you're putting it into []
, you are creating an array which contains an array as your items as the first element.
case "DEL_ITEM":
return {
...state,
items: state.items.filter((item) => item.id !== action.payload),
};
is therefore correct.