使用 useEffect Hook 过滤 Table 数据导致组件无限重新渲染

Filtering Table data with useEffect Hook causing component to re-render infinitely

我正在尝试使用搜索栏组件动态过滤由 API 请求填充的 table 的内容,但是当我使用此实现时,组件会无限地重新呈现并重复发送相同的 API 请求。 useEffect() 钩子:

React.useEffect(() => {
        const filteredRows = rows.filter((row) => {
            return row.name.toLowerCase().includes(search.toLowerCase());
        });
        if (filteredRows !== rows){
            setRows(filteredRows);
        }        
    }, [rows, search]);

我在这个实现中遗漏了什么会导致无限重新渲染的东西吗?

编辑 1: 对于进一步的上下文,添加引用该组件的相关代码段可能会导致相同的行为。

呈现 table 的父组件内的函数通过我编写的 webHelpers 库调用我的 API 以简化 API 请求使用。

function fetchUsers() {
        webHelpers.get('/api/workers', environment, "api", token, (data: any) => {
            if (data == undefined || data == null || data.status != undefined) {
                console.log('bad fetch call');
            }
            else {
                setLoaded(true);   
                setUsers(data);
                console.log(users);
            }
        });
    }

    fetchUsers();

编辑 2: 到目前为止采取的尝试解决此问题的步骤,根据评论编辑了挂钩:

 React.useEffect(() => {
        setRows((oldRows) => oldRows.filter((row) => {
            return row.name.toLowerCase().includes(search.toLowerCase());
        }));    
    }, [search]);

编辑 3: 找到解决方案,我已经标记了@Dharmik 的答案,指出如何管理 Effect 调用,因为这导致我调查父组件并找出导致组件反复重新渲染的原因。事实证明,父元素重复使用了一个 useEffect 钩子 运行,它重新呈现页面并导致呈现循环和 API 调用。我的解决方案是删除这个钩子,子组件继续渲染,没有循环。

发生这种情况是因为您已将 rows 添加到 useEffect 依赖项数组,当有人向 search bar 中输入内容时,rows 会被过滤并且 rows 持续更新中。

因此 useEffect 一次又一次地被调用。从 useEffect 依赖项数组中删除 rows,它应该可以正常工作。

我想补充 Dharmik 的回答。依赖关系应该保持详尽无遗(React 团队推荐)。我认为错误是 filteredRows !== rows 使用了引用相等性。但是 rows.filter(...) returns 一个新的引用。所以你可以使用某种深度相等性检查,或者在我看来更好的方法是:

React.useEffect(() => {
        setRows((oldRows) => oldRows.filter((row) => {
            return row.name.toLowerCase().includes(search.toLowerCase());
        }));
    }, [search]);