I have a to do's list that has a <li>
with an edit Button and Toggle Button.
Actually i've made a reducer to do the actions: add, delete, toggle. It's almost working fine, but it is executing the actions twice. The toggle function for example is putting the attribute done to true, then the function execute again and the toggle function put the attribute to false again.
Here is my project in github: https://github.com/brenosantin96/TodoListWithUseReducer01
Here is the Reducer code i've did:
function reducer(stateTodos: todoType[], actionType: actionType) {
switch (actionType.type) {
case 'ADD-TODO':
if (actionType.payload?.id && actionType.payload?.name) {
let newStateTodos = [...stateTodos];
newStateTodos.push({
id: actionType.payload?.id,
name: actionType.payload?.name,
done: actionType.payload?.done
})
console.log("Adicionado TODO");
return newStateTodos;
break;
}
case 'DEL-TODO':
if (actionType.payload?.id) {
let newStateTodos = [...stateTodos];
newStateTodos = newStateTodos.filter((item) => item.id !== actionType.payload?.id)
console.log("Deletado TODO");
return newStateTodos;
break;
}
case 'TOGGLE-TODO':
if (actionType.payload?.id) {
let newStateTodos = [...stateTodos];
for (let item of newStateTodos) {
if (item.id === actionType.payload?.id) {
item.done = !item.done
}
}
console.log(newStateTodos);
return newStateTodos;
}
default:
return stateTodos;
}
}
Below is the function component:
function App2() {
const [inputTodo, setInputTodo] = useState('');
const [stateTodos, dispatch] = useReducer(reducer, initialToDos);
//controlling input always when value changes
const handleInputTodo = (e: ChangeEvent<HTMLInputElement>) => {
setInputTodo(e.target.value);
}
//Function that makes add todo.
const handleForm = (e: React.FormEvent) => {
e.preventDefault();
dispatch({
type: 'ADD-TODO', payload: {
id: parseInt(uuidv4()),
name: inputTodo,
done: false
}
});
setInputTodo('');
}
//Function that calls deleteTodo to delete a todo
const handleDelTodo = (id: number) => {
dispatch({
type: 'DEL-TODO', payload: {
id: id
}
});
}
//Funcao that calls Toggle-TODO, it should toggle the done to false or the false to true.
const handleToggleTodo = (id: number) => {
dispatch({
type: 'TOGGLE-TODO', payload: {
id
}
})
}
return (
<div>
<form action="submit" onSubmit={handleForm}>
<input type="text" value={inputTodo} onChange={handleInputTodo} />
<button type='submit'>ENVIAR</button>
</form>
<div>
LIST:
<ul>
{stateTodos.map((item) => {
return (
<li key={item.id}>
{item.id} - {item.name}
<button onClick={() => handleDelTodo(item.id)}> DELETE </button>
<button onClick={() => handleToggleTodo(item.id)}>CHECK</button>
</li>
)
})}
</ul>
</div>
</div>
)
}
Any idea of where im missing something ?