skip to Main Content

I have a problem wanting to conditionally render a task group depending on whether they are marked as performed or pending.

function TaskList() {
  const { tasks } = useContext(TaskContext);

  return tasks.length === 0 ? (
    <h2>No hay tareas agregadas</h2>
  ) : (
    <section className="task-list">
      <div className="pending-task">
        <h3>Tareas pendientes:</h3>
        <ul className="list">
          {tasks.filter((t) => t.done === false).length === 0 ? (
            <h4>No hay tareas por realizar</h4> // In case there is no task to do, you should render this
          ) : (
            tasks
              .filter((t) => t.done === false)
              .map((t, i) => <TaskCard key={t.id} task={t} index={i} />) //here are rendered those that are pending
          )}
        </ul>
      </div>
      <div className="done-task">
        <h3>Tareas realizadas:</h3>
        <ul className="list">
          {tasks.filter((t) => t.done === true).length === 0 ? (
            <h4>No ha realizado ninguna tarea</h4> //In case no task has been performed I still want to show this
          ) : (
            tasks
              .filter((t) => t.done === true)
              .map((t, i) => <TaskCard key={t.id} task={t} index={i} />) //here are rendered the ones I already made
          )}
        </ul>
      </div>
    </section>
  );
}
 

But when I put it to the test and click the button to mark the task as done, I throw the following error:

Uncaught TypeError: Cannot read properties of undefined (reading 'done') at TaskList.jsx:16:34

What would be this line here:

tasks.filter((t) => t.done === false).length === 0

I am aware that this error can occur because when filtering an array without elements, you cannot find the specified done property.

the funny thing is that after the app has been bugled due to the aforementioned error, if I refresh the page, the app works again and the task in which I clicked appears marked, that is, the bug is deleted, so I don’t know what I’m doing wrong, I have a couple of months practicing with react and there are things I’m learning.

3

Answers


  1. Chosen as BEST ANSWER

    This is part of my context:

    const [tasks, setTask] = useState([]);
    
      const [checked, setChecked] = useState(false);
    
      useEffect(() => setTask(data), []); 
    
    // Here the value of *data* comes from an import that is an array that reads the tasks stored in the browser localstorage
    
    

  2. If you are sure that that the tasks array in the TaskContext is properly initialized and contains valid task objects with the done property and tasks array is not null or undefined when the TaskList component is rendered. You can add a null check before rendering the component to handle such cases.

    if (!tasks) {
      return null // or render a loading state
    }
    
    
    Login or Signup to reply.
  3. You can modify this line

    tasks.filter((t) => t.done === false).length === 0
    

    with

    tasks.some((t) => !t?.done)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search