如何确保父组件将相同的prop函数传递给子组件以避免重新渲染

时间:2020-06-30 02:52:36

标签: reactjs react-hooks

当前,我设置了两个组件,其中父级呈现一些数据并处理检索,而子级则是过滤器。该过滤器允许用户按状态或关键字进行过滤。没什么。

现在这是一个分页系统。父级首次提出数据请求后,如果需要更多信息,则会为他们提供下一个页面ID。但是,如果过滤器已更新,则该下一页ID会被删除,因为这样做不好。

所以我要做的是将一个函数从父级传递给子级updateFilter()。如果过滤器组件的状态为更新,它将调用父组件并运行updateFilter()。已更新的值之一包含在useEffect()依赖项数组中,因此父级然后使用新的过滤器请求新数据。容易。

问题在于设置孩子的useEffect()。 Eslint告诉我,我需要在依赖项数组中添加props.updateFilter,尽管我可以忽略它,但是我觉得这样做是错误的。但是,父级有相当多的状态会更新,当更新时,它会将updateFilter()的新副本向下传递给子级,从而导致其错误触发。

如何解决此问题?我可以告诉孩子以某种方式仅使用此功能的静态版本吗?还是只将props.updateFilter从依赖项数组中排除?下面是我的组件的大致伪代码。

Parent {
    const [stateVal, setStateVal] = useState(...);
    
    function updateFilter(filterStatus) {
        ...
        setStateVal(filterStatus);
    }

    useEffect(() => ..., [stateVal]);

    return <Child updateFilter={updateFilter} />
}

Child {
    const [filterStatus, setStatus] = useState(...);

    useEffect(() => {
        props.updateFilter(filterStatus);
    }, [filterStatus] // Adding `props` here is what I think I should do, but that causes the issue. Apparently the `props` val changes every time Parent's state changes
   
    return ( ... );
}

1 个答案:

答案 0 :(得分:3)

如何解决此问题?我可以告诉孩子只使用一个 该功能的静态版本以某种方式?

是的!

因此,如果在依赖项数组中包含props.updateFilter,则可能会出现问题。您调用该函数,它将导致您的父组件重新呈现。你猜怎么着?父级创建一个新的updateFilter函数(它做同样的事情,但是又做了一个新的函数,对该函数的引用是一个新值,所有React都会对其进行检查)。这将导致子项重新渲染,这将导致您的useEffect运行,因为其依赖项是一个新函数。太糟糕了!

所以...添加useCallback

function updateFilter = useCallback((filterStatus) => {
    ...
    setStateVal(filterStatus);
}, []);

useCallback一次创建该函数,并且仅在其依赖项发生更改时才进行新引用(应如此)。它有更多的开销,但是如果我不确定我会使用它。

此外,奖金,在解决了这些问题之后,我使用setState(previousValue => previousValue + 1)的形式要多于setState(previousValue + 1),因为它有很多好处。 previousValue不必在依赖项数组中,可以在一个渲染周期中堆叠多个setState(而不使用初始值)。