如何实现 inputSearch 组件,以便用户通过输入几个字母即可找到某个任务?

问题描述 投票:0回答:1

目前,我已经基本完成了用户查找某个任务的功能。我使用一个名为 isTaskListEmpty 的变量来根据其状态呈现不同的内容。但此功能仅在用户键入第二个字母时才起作用。当用户键入第一个字母时,没有任何反应,因为 isTaskListEmpty 变量为 false。但是,当用户键入第二个字母并发生重新渲染时,我的 inputSearch 组件将起作用。我知道问题出在变量 isTaskListEmpty 上。也许有人可以提供有关我如何克服这个问题的线索。当用户在输入字段中输入第一个字母时,如何使 isTaskListEmpty 变量立即更改?

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.

javascript reactjs arrays redux react-hooks
1个回答
0
投票

isTaskListEmpty 正在异步更新,导致渲染相应内容的效果出现延迟。

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>
  );
};

试试这个

© www.soinside.com 2019 - 2024. All rights reserved.