skip to Main Content

For now, I have almost finished implementing the functionality for users to find a certain task. I am using a variable called isTaskListEmpty to render different content depending on its state. But this functionality only works when the user types the second letter. When the user types the first letter, nothing happens because the isTaskListEmpty variable is false. However, when the user types the second letter and the re-rendering occurs, my inputSearch component works. I understand that the problem lies in the variable isTaskListEmpty. Perhaps someone can provide a clue on how I can overcome this issue. How can I make the isTaskListEmpty variable change immediately when the user enters the first letter in the input field?

import React, { useState } from "react";
import InputTask from "../InputTask/InputTask";
import HeaderOfTaskList from "../HeaderOfTaskList/HeaderOfTaskList";
import Task from "../Task/Task";
import { useDispatch, useSelector } from "react-redux";
import { removeTask, addTask } from "../../store/actions";
import InputSearch from "../InputSearch/InputSearch";
import useInput from "../../hooks/useInput";
import "./TaskList.css";

export const TaskList = () => {
  const dispatch = useDispatch();
  const tasks = useSelector((state) => state.tasklist);
  const input = useInput();
  const [isTaskListEmpty, setIsTaskListEmpty] = useState(false);
  const [searchTerm, setSearchTerm] = useState("");

  const filteredTasks = tasks.filter((task) =>
    task.title.toLowerCase().includes(searchTerm.toLowerCase())
  );

  const handleInputChange = (value) => {
    setIsTaskListEmpty(!isTaskListEmpty);
    setSearchTerm(value);

    console.log(isTaskListEmpty);
  };

  const handleDelete = (id) => {
    dispatch(removeTask(id));
  };

  const handleAddTask = (tasklist) => {
    dispatch(addTask(tasklist));

    console.log(isTaskListEmpty);
  };

  return (
    <div>
      <InputTask addTask={handleAddTask} />
      <InputSearch onInputChange={handleInputChange} />
      <HeaderOfTaskList />
      {!isTaskListEmpty ? (
        <ul>
          {filteredTasks
            .filter((task) =>
              task.title.toLowerCase().includes(input.value.toLowerCase())
            )
            .map((task) => (
              <Task
                task={task}
                key={task.id}
                onDelete={() => handleDelete(task.id)}
              />
            ))}
        </ul>
      ) : (
        <ul>
          {tasks.map((task) => (
            <Task
              task={task}
              key={task.id}
              onDelete={() => handleDelete(task.id)}
            />
          ))}
        </ul>
      )}
    </div>
  );
};
import { useState } from "react";

const useInput = (defaultValue = "") => {
  const [value, setValue] = useState(defaultValue);
  return {
    value,
    onChange: (e) => {
      setValue(e.target.value);
    },
  };
};

export default useInput;

I created the filteredTasks function to find matches, and I also implemented the useInput custom hook.

2

Answers


  1. Chosen as BEST ANSWER
     export const TaskList = () => {
      const dispatch = useDispatch();
      const tasks = useSelector((state) => state.tasklist);
      const input = useInput();
      const [searchTerm, setSearchTerm] = useState("");
    
      const filteredTasks = tasks.filter((task) =>
        task.title.toLowerCase().includes(searchTerm.toLowerCase())
      );
      const isTaskListEmpty = filteredTasks.length === 0;
    
      const handleInputChange = (value) => {
        setSearchTerm(value);
      };
    
      const handleDelete = (id) => {
        dispatch(removeTask(id));
      };
    
      const handleAddTask = (tasklist) => {
        dispatch(addTask(tasklist));
      };
    
      return (
        <div>
          <InputTask addTask={handleAddTask} />
          <InputSearch onInputChange={handleInputChange} />
          <HeaderOfTaskList />
          {!isTaskListEmpty ? (
            <ul>
              {filteredTasks
                .filter((task) =>
                  task.title.toLowerCase().includes(input.value.toLowerCase())
                )
                .map((task) => (
                  <Task
                    task={task}
                    key={task.id}
                    onDelete={() => handleDelete(task.id)}
                  />
                ))}
            </ul>
          ) : (
            <ul>
              {tasks.map((task) => (
                <Task
                  task={task}
                  key={task.id}
                  onDelete={() => handleDelete(task.id)}
                />
              ))}
            </ul>
          )}
        </div>
      );
    };
    

  2. isTaskListEmpty is being updated asynchronously, causing a delay in its effect on rendering the appropriate content.

    import React, { useState, useEffect } from "react";
    import InputTask from "../InputTask/InputTask";
    import HeaderOfTaskList from "../HeaderOfTaskList/HeaderOfTaskList";
    import Task from "../Task/Task";
    import { useDispatch, useSelector } from "react-redux";
    import { removeTask, addTask } from "../../store/actions";
    import InputSearch from "../InputSearch/InputSearch";
    import useInput from "../../hooks/useInput";
    import "./TaskList.css";
    
    export const TaskList = () => {
      const dispatch = useDispatch();
      const tasks = useSelector((state) => state.tasklist);
      const input = useInput();
      const [isTaskListEmpty, setIsTaskListEmpty] = useState(false);
      const [searchTerm, setSearchTerm] = useState("");
    
      useEffect(() => {
        setIsTaskListEmpty(filteredTasks.length === 0);
      }, [searchTerm, tasks]);
    
      const filteredTasks = tasks.filter((task) =>
        task.title.toLowerCase().includes(searchTerm.toLowerCase())
      );
    
      const handleInputChange = (value) => {
        setSearchTerm(value);
      };
    
      const handleDelete = (id) => {
        dispatch(removeTask(id));
      };
    
      const handleAddTask = (tasklist) => {
        dispatch(addTask(tasklist));
      };
    
      return (
        <div>
          <InputTask addTask={handleAddTask} />
          <InputSearch onInputChange={handleInputChange} />
          <HeaderOfTaskList />
          {!isTaskListEmpty ? (
            <ul>
              {filteredTasks
                .filter((task) =>
                  task.title.toLowerCase().includes(input.value.toLowerCase())
                )
                .map((task) => (
                  <Task
                    task={task}
                    key={task.id}
                    onDelete={() => handleDelete(task.id)}
                  />
                ))}
            </ul>
          ) : (
            <ul>
              {tasks.map((task) => (
                <Task
                  task={task}
                  key={task.id}
                  onDelete={() => handleDelete(task.id)}
                />
              ))}
            </ul>
          )}
        </div>
      );
    };
    

    try this

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