Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React / Typescript : pushing obj into array of object and undefined type

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.

like image 313
Touk Avatar asked Nov 06 '22 23:11

Touk


1 Answers

Updated

You can try this:

  const handleSubmitNewTodo = () => {
    let newTodos = [...todos];
    console.log(newTask, newTodos);
    if (newTask) {
      newTodos.push(newTask);
      setTodos(newTodos);
      setNewTask(undefined);
    }
  };

I have added the setNewTask to undefined to maintain the initial state after adding the new todo to the todo list.

like image 54
Shivam Verma Avatar answered Nov 11 '22 04:11

Shivam Verma