I'm beginnig my journey into TypeScript in React and to experiment what I've learn, I've try a simple Todo App. Everything is working fine except ONE things !
When I'm pushing 'newTask' When I'm hovering 'newTask' here's the hint (Google Trad from French) :
The 'Todo | undefined 'is not attributable to the parameter of type' Todo '. Cannot assign type 'undefined' to type 'Todo'.
I guess it's related to something here :
let [newTask, setNewTask] = useState<Todo>();
because if I type useState<any>();
I don't have any error..
Here's the full code :
import React, { useState } from "react";
// INTERFACES
interface Todo {
id: number;
text: string;
completed: boolean;
}
export const TodoComponent = () => {
// STATE
const initialTodos: Todo[] = [
{ id: 0, text: "Todo 1", completed: false },
{ id: 1, text: "Todo 2", completed: true },
{ id: 2, text: "Todo 3", completed: false },
];
const [todos, setTodos] = useState<Todo[]>(initialTodos);
let [newTask, setNewTask] = useState<Todo>();
// ACTIONS
const handleClickOnComplete = (id: number, completed: boolean) => {
const newTodos = [...todos];
newTodos[id].completed = !completed;
setTodos(newTodos);
};
const handleRemove = (todo: Todo) => {
const newTodos = todos.filter((t) => t !== todo);
setTodos(newTodos);
};
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setNewTask({
id: todos.length,
text: event.target.value,
completed: false,
});
};
const handleSubmitNewTodo = () => {
const newTodos = [...todos];
console.log(newTask, newTodos);
newTodos.push(newTask);
setTodos(newTodos);
};
return (
<div>
<h1>Todo App !</h1>
<div>
{todos.map((todo) => {
return (
<div key={todo.id}>
{todo.id} - {todo.text} -{" "}
<input
type="checkbox"
checked={todo.completed}
onChange={() => handleClickOnComplete(todo.id, todo.completed)}
/>
<button onClick={() => handleRemove(todo)}>Remove task</button>
</div>
);
})}
</div>
<hr />
<div>
<input placeholder="Add todo" type="text" onChange={handleChange} />
<button onClick={handleSubmitNewTodo}>Add todo</button>
</div>
</div>
);
};
Problem is in handleSubmitTodo
Thanks for your help and advices. Take care.
CodePudding user response:
Updated
You can try this:
const handleSubmitNewTodo = () => {
let newTodos = [...todos];
console.log(newTask, newTodos);
if (newTask) {
newTodos.push(newTask);
setTodos(newTodos);
setNewTask(undefined);
}
};
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
I have added the setNewTask to undefined to maintain the initial state after adding the new todo to the todo list.
CodePudding user response:
Like @jcalz suggests, adding a condition around the push seems to do the trick, is it the better way ?
const handleSubmitNewTodo = () => {
const newTodos = [...todos];
if (newTask) {
newTodos.push(newTask);
}
setTodos(newTodos);
};