开发者社区 问答 正文

每次渲染前如何在UseEffect React Hooks中重置数据?

这是情况。我useEffect过去曾过滤一些数据,但效果很好。这是代码和codesandbox。 const data = [ {name: 'aml', age: 10}, {name: 'abcb', age: 12}, {name: 'asr', age: 20}, {name: 'plo', age: 30}, {name: 'bvcq', age: 15}, {name: 'bfro', age: 21}, {name: 'zxwh', age: 19} ]

function App() { const [keyword, setKeyword] = React.useState('') const [result, setResult] = React.useState(data) const [isAged, setIsAged] = React.useState(false) const [isNameLength3, setIsNameLength3] = React.useState(false) React.useEffect(() => { const doSearch = () => { // setResult(data) if (isAged) { setResult(result.filter(item => item.age >= 20)) } if (isNameLength3) { setResult(result.filter(item => item.name.length === 3)) } if (keyword) { setResult(result.filter(item => item.name.toLowerCase().includes(keyword.toLowerCase()))) } } doSearch() }, [isAged, keyword, isNameLength3, result]) return (

<input value={keyword} type='text' onChange={(e) => setKeyword(e.currentTarget.value)} placeholder='search...' />
<input onChange={() => setIsAged(!isAged)} type='checkbox' checked={isAged} /> Age >= 20 <input onChange={() => setIsNameLength3(!isNameLength3)} type='checkbox' checked={isNameLength3} /> NameLength3
{ result && result.length > 0 && result.map((item, index) => <p key={'result' + index}>{item.name} -> {item.age}

) }
) } 在result当我改变搜索关键字或复选框改变每次。但是没有回头路了。

例如,我选中了两个复选框,结果将是:

asr -> 20

plo -> 30 现在我输入a,结果变为

asr -> 20 问题是,当我删除时a,我想要的结果

asr -> 20

plo -> 30 我知道result被削减了,但是我该如何实现呢?

我认为它应该搜索是否已使用原始数据更改了任何过滤器(复选框和关键字)。

所以我在一开始就尝试了useEffect。

setResult(data) 但不幸的是,它没有按我预期的那样工作。

展开
收起
被纵养的懒猫 2019-09-30 14:57:11 1104 分享 版权
阿里云 AI 助理回答

从你提供的代码片段来看,你正在使用React Hooks(useState和useEffect)来实现一个具有动态过滤功能的应用。你的数据是一个包含姓名和年龄的对象数组。用户可以通过输入关键词搜索、勾选年龄条件(大于等于20岁)或名字长度条件(长度为3)来过滤数据。

问题似乎在于你提到的“useEffect过去曾过滤一些数据,但效果很好”,这表明当前可能遇到了某种问题。不过,根据代码本身,并没有直接显现出明显的错误。为了更好地帮助你,我需要了解具体的故障表现或者报错信息。

不过,这里有几个潜在的优化点和注意事项:

  1. 依赖项数组:在useEffect的依赖项数组中直接包含result可能会导致无限循环,因为每次setResult更新result时,都会触发useEffect重新执行。通常,我们不希望直接依赖于状态变量自身作为触发更新的条件,除非有特殊需求且能确保不会造成循环调用。你可以尝试移除result,只保留那些外部影响因素(如isAgedkeywordisNameLength3)作为依赖项。

  2. 性能优化:频繁的.filter()操作可能会在大数据量下影响性能。如果数据集非常大,可以考虑使用memoization(记忆化)或其他策略减少不必要的计算。

  3. 逻辑顺序:当前的过滤逻辑是依次检查每个条件并立即设置结果,这意味着后面的过滤会覆盖前面的结果。如果你的意图是同时满足所有条件进行过滤,这种逻辑是正确的。但如果是要组合多个条件(即满足任意一个条件即可),则需要调整逻辑。

  4. 代码清晰度:虽然代码已经很直观,但为了提高可读性和维护性,可以考虑将过滤逻辑封装成单独的函数,这样不仅使组件更简洁,也便于未来扩展或调试。

假设你想要解决的是避免因包含result而导致的潜在无限循环问题,你可以修改useEffect如下:

React.useEffect(() => {
    const doSearch = () => {
        let filteredData = data; // 从原始数据开始过滤

        if (isAged) {
            filteredData = filteredData.filter(item => item.age >= 20);
        }
        
        if (isNameLength3) {
            filteredData = filteredData.filter(item => item.name.length === 3);
        }
        
        if (keyword) {
            filteredData = filteredData.filter(item => 
                item.name.toLowerCase().includes(keyword.toLowerCase())
            );
        }

        setResult(filteredData);
    };

    doSearch();
}, [isAged, keyword, isNameLength3]); // 移除了result作为依赖项

请根据你的具体需求调整代码,并提供更多信息以便获得更精确的帮助。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答