目前我设置了一个两个组件,其中父级渲染一些数据并处理检索,子级是过滤器。此筛选器允许用户按状态或关键字进行筛选。没什么好看的。
现在这是一个分页系统。在父级发出初始数据请求后,系统会为他们提供下一个页面 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 ( ... );
}
我该如何解决这个问题?我可以告诉孩子只使用 这个函数的静态版本不知何故?
是的!
因此,如果依赖项数组中包含props.updateFilter
则会遇到问题。调用该函数,它会导致父组件重新呈现。你猜怎么着?父级创建一个新的updateFilter
函数(它做同样的事情,但它做了一个新的,对该函数的引用是一个新值,这是所有React
检查(。这会导致子项重新呈现,从而导致useEffect
运行,因为它的依赖项是一个新函数。这很糟糕!
所以... 添加useCallback
function updateFilter = useCallback((filterStatus) => {
...
setStateVal(filterStatus);
}, []);
useCallback
创建函数一次,并且仅在其依赖项更改(应更改(时才创建新引用。它的开销有点大,但如果我不确定我会使用它。
另外,奖金,在处理完这些问题后,我使用setState(previousValue => previousValue + 1)
形式比setState(previousValue + 1)
多得多,因为它有很多好处。previousValue
不必位于依赖项数组中,并且可以在一个渲染周期中堆叠多个setState
(而不是使用初始值(。