I am trying to use useReducer hook to add and delete items of a todo list in react.
The weird thing happend when I tried to delete it.
The error message is TypeError Cannot read properties of undefined (reading 'map').
The funny thing is if I changed the action to the same as addItem, it could function but if I change to anythign else like simply console.log it would break and showed the same message TypeError Cannot read properties of undefined (reading 'map').
Can anyone help me to find out what the probelm is? I really appreciate it.
import React, { useState, useReducer } from "react";
import { FaBeer } from "react-icons/fa";
import ToDoItem from "./components/ToDoItem";
import "./App.css";
function App() {
const [inputText, setInputText] = useState("");
const [state, dispatch] = useReducer(reducer, [], init);
function init(initArray) {
return { todos: initArray };
}
function reducer(state, action) {
switch (action.type) {
case "addItem":
return { todos: [...state.todos, action.payload.inputText] };
case "deleteItem":
return state.todos.filter((item, index) => {
return index !== action.payload.id;
});
// return { todos: [...state.todos, action.payload.id] };
default:
return state.todos;
}
}
function handleChange(event) {
const newValue = event.target.value;
setInputText(newValue);
}
function addItem(e) {
e.preventDefault();
dispatch({ type: "addItem", payload: { inputText: inputText } });
setInputText("");
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<form onSubmit={addItem}>
<input onChange={handleChange} type="text" value={inputText} />
<button type="submit">
<span>Add</span>
</button>
</form>
</div>
<div>
<ul>
{state.todos.map((eachItem, index) => (
<ToDoItem
key={index}
id={index}
text={eachItem}
dispatch={dispatch}
/>
))}
</ul>
</div>
</div>
);
}
export default App;
This is the toDoItem component
import React from "react";
import audio from './clickSound.wav';
import CheckBox from "./CheckBox";
import Delete from "./Delete";
function ToDoItem(props) {
const [clicked, setClicked] = React.useState(false);
function cross() {
setClicked((prevValue) => {
return !prevValue;
});
}
function playSound(){
const sound = new Audio(audio)
sound.play()
}
return (
<div>
<CheckBox />
<label>
<input type="checkbox" className="normalCheckbox" onClick={()=>{cross();playSound();}} />
<li style={{ textDecoration: clicked ? "line-through" : "none" }}>
{props.text}
</li>
</label>
<Delete
onClick={() =>
props.dispatch({ type: "deleteItem", payload: { id: props.id } })
}
/>
</div>
);
}
export default ToDoItem;
this is delete component
import React from 'react';
import { AiFillDelete} from "react-icons/ai";
const Delete = props => {
return <button onClick={props.onClick}type="button"> <AiFillDelete/> </button>
};
export default Delete;
replace the action with the same as additem with id, it works
replace the action with console.log, it ran four times and then break with the error message