skip to Main Content

I am going through the React Docs where I am trying to implement a Todo app. Most of the code is same as per the doc except it does not have an edit / delete functionality in the listing.

Problem – On adding some text in the input box and clicking on the add button, the Task List is not getting updated. Though in the React Dev Tool I can see that the task is added to the list.

Confusion – Now as I am saving the tasks in state in the Parent component(TaskApp) and changing the state should change the prop and TaskList component need to be re render which is not happening, let me know what I am missing here concept wise as in the official docs as well they are not using any hooks but still its working for them.

Codesandbox Linkhttps://codesandbox.io/s/confident-mcclintock-dryxtz?file=/src/TaskApp.js

Code –

TaskApp.js File –

import React, { useState } from "react";
import AddTask from "./AddTask";
import TaskList from "./TaskList";

const initialsTasks = [
  { id: 10, text: "Visit Paris", done: false },
  { id: 11, text: "Visit Tokyo", done: true },
  { id: 12, text: "Visit Washington DC", done: false }
];
let nextId = 13;

function TaskApp() {
  const [tasks, setTasks] = useState(initialsTasks);

  function handleAddTask(text) {
    setTasks((prevTasks) => {
      return [
        ...prevTasks,
        {
          id: nextId++,
          task: text,
          done: false
        }
      ];
    });
  }

  return (
    <div className="task-app">
      <h3>World Itinerary</h3>
      <AddTask onAddTask={handleAddTask} />
      <TaskList tasks={tasks} />
    </div>
  );
}

export default TaskApp;

AddTask.js File –

import { useState } from "react";

export default function AddTask({ onAddTask }) {
  const [text, setText] = useState("");

  function handleChange(e) {
    setText(e.target.value);
  }

  function handleClick() {
    onAddTask(text);
    setText("");
  }

  return (
    <div className="add-task">
      <input
        type="text"
        placeholder="Add Task"
        value={text}
        onChange={handleChange}
      />
      <button onClick={handleClick}>Add</button>
    </div>
  );
}

TaskList.js File –

export default function TaskList({ tasks }) {
  return (
    <div className="task-list">
      {tasks.map((task) => {
        return (
          <div className="task" key={task.id}>
            {task.text}
          </div>
        );
      })}
    </div>
  );
}

2

Answers


  1. This is why they’re not appearing, the div elements are actually being created, but the text is blank.

    {
      id: nextId++,
      task: text,
      done: false
    }
    

    Fix:

    { id: nextId++, text, done: false }
    

    Or:

    { id: nextId++, text: text, done: false }
    

    (They are effectively the same).

    Login or Signup to reply.
  2. The issue in your code lies in the handleAddTask function in the TaskApp component. In the new task object that you’re adding to the tasks array, you’re using the property name task instead of text. This causes a discrepancy between the property name used in the initial tasks and the one used in the added tasks.

      function handleAddTask(text) {
    setTasks((prevTasks) => {
      return [
        ...prevTasks,
        {
          id: nextId++,
          text: text,
          done: false
        }
      ];
    });
    

    }

    that’s it !

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search