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 列表中搜索已完成或未完成的待办事项标题,具体取决于您切换的位置,目前搜索在所有待办事项中进行。
重现案例
- 在 codesandbox
中启动应用程序
- 切换开关
- 搜索元素(它在所有待办事项列表中搜索,而不是通过已完成或未完成的结果列表搜索)
相关代码如下
搜索方法
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
状态是在逆逻辑上工作。当我打开开关时,isCompleted
是 false
但它应该是 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”而不是新的状态变量。
我正在检索数据列表并从 todos, then i have built with Switch Material UI 组件列表中搜索标题名称以切换已完成和未完成的待办事项。
您可以在此处查看完整演示 => https://codesandbox.io/s/so-68247206-forked-sx9kv?file=/src/App.js
现在我想在 todos/tasks 列表中搜索已完成或未完成的待办事项标题,具体取决于您切换的位置,目前搜索在所有待办事项中进行。
重现案例
- 在 codesandbox 中启动应用程序
- 切换开关
- 搜索元素(它在所有待办事项列表中搜索,而不是通过已完成或未完成的结果列表搜索)
相关代码如下
搜索方法
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
状态是在逆逻辑上工作。当我打开开关时,isCompleted
是 false
但它应该是 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”而不是新的状态变量。