React - 无论更改顺序如何,同时对给定数据进行搜索和过滤

React - Make search and filter work on a given data at same time irrespective of the order of change

我正在检索数据列表并从 todos, then i have built with Switch Material UI 组件列表中搜索标题名称以切换已完成和未完成的待办事项。

您可以在此处查看完整演示 => https://codesandbox.io/s/so-68247206-forked-sx9kv?file=/src/App.js

现在我想在 todos/tasks 列表中搜索已完成或未完成的待办事项标题,具体取决于您切换的位置,目前搜索在所有待办事项中进行。

重现案例

相关代码如下

搜索方法

  const handleSearch = (event) => {
    let value = event.target.value.toLowerCase();
    let result = [];
    result = tasks.filter((data) => {
      return data.title.search(value) !== -1;
    });
    setFilteredData(result);
  };

完整方法

  const getCompleted = (e, value) => {
    let result = [];
    let switchValue = e.target.checked;
    result = tasks.filter(({ completed }) => completed === switchValue);
    setFilteredData(result);
    setIsCompleted(!switchValue);
    setText(isCompleted ? "Yes" : "No");
  };

如何更改我的搜索方法以查看已完成和未完成的待办事项?

您必须将搜索值和开关值都保存在状态中,并使用 useEffect 来过滤这些值。检查下面的代码分支

https://codesandbox.io/s/so-68247206-forked-nkuf3?file=/src/App.js

您的 handleSearch 方法略有修改。当您过滤 tasks 时,您可以检查是否已使用 isCompleted 状态打开已完成的开关。您所需要的只是 filter 方法中的一个附加条件,用于处理已完成的场景。以下更新的 handleSearch 方法工作正常。

  const handleSearch = (event) => {
    let value = event.target.value.toLowerCase();
    let result = [];
    console.log(value);
    let filterCompleted = false;
    if (!isCompleted) filterCompleted = true;
    console.log({ filterCompleted });
    result = tasks.filter((data) => {
      if (filterCompleted)
        return data.completed && data.title.search(value) !== -1;
      else return !data.completed && data.title.search(value) !== -1;
    });
    setFilteredData(result);
  };

我在 handleSearch 中使用了一个局部变量来检查您是否已打开完成按钮。如果打开,在过滤时我只过滤那些 completed 属性 设置为 true 的任务,反之亦然。您可以在此处检查这是否有效 https://codesandbox.io/s/so-68247206-forked-4iz7p?file=/src/App.js.

注意:我感觉isCompleted状态是在逆逻辑上工作。当我打开开关时,isCompletedfalse 但它应该是 true。您可以尝试修复此问题或重命名状态(如果反向逻辑是故意的并且您只是搞砸了命名状态)。无论如何,这不会影响解决方案,但会使调试变得困难并增加一些混乱。

您在 handleSearch 中的过滤器从原始任务数组中搜索,这可能不是您想要的:

   const handleSearch = (event) => {
    let value = event.target.value.toLowerCase();
    let result = tasks; //Assigning initial value to result
    if(isCompleted){
     result =  result.filter(({ completed }) => completed === isCompleted)
    } //only if isCompleted is true, filter the array first
    result = result.filter((data) => {
      return data.title.search(value) !== -1;
    }); //Filter the array based on search term
    setFilteredData(result);
  };

此外,您的 getCompleted 正在使用 (!switchValue) 设置复选框的反向值。您可以将其与额外的参数 value 一起更改,该参数未在您的 onChange 调用中考虑。

 const getCompleted = (e) => {
    
    let switchValue = e.target.checked;
    let result = tasks.filter(({ completed }) => completed === switchValue);
    setFilteredData(result);
    setIsCompleted(switchValue);
    setText(switchValue ? "Yes" : "No"); //Is text state variable really required?
  };

我在这里尝试修复它:CodeSandbox

话虽这么说,但我建议不要使用可以相互派生的多个状态变量。您的 text 状态变量仅用于查看目的,其值完全依赖于 isCompleted。您可以在 return 函数中使用条件运算符来显示“Yes/No”而不是新的状态变量。