今天开发遇到一个实际问题,一个组件中使用了一个自定义hooks,这个hooks的参数是一个数组,由于页面改造所以需要对这个参数进行一次转换,于是我就把参数从这样:
变成了这样:
问题出现了~,hooks返回的方法开始无限调用了。。。
检查代码发现,hooks返回的函数loadProjectList的调用是通过useEffect来实现了。所以无限调用的原因应该就是loadProjectList函数一直在改变。
进入hooks
function useSelectProject(orgs?: ISelectOptionState[]) {
const [projectList, setProjectList] = useState<IProject[]>([]);
const loadProjectList = useCallback(
(keyword?: string) => {
if (!orgs?.length) {
setProjectList([]);
return;
}
ProjectApi.orgProjectList({ keyword, orgIds: orgs.map((v) => v.value as number) })
.then(setProjectList)
.catch(() => setProjectList([]));
},
[orgs]
);
const [updateKeyword] = useDebounce(loadProjectList, debounceTime);
return { projectList, updateKeyword, loadProjectList };
}
export default useSelectProject;
发现这loadProjectList是通过useCallback,依赖于orgs来实现更新的。
原来症结在这儿~
以前的orgs是state对象上面的一个属性,所以不会无限改变。但是现在每次调用loadProjectList函数之后,里面会调用setProjectList,倒置组件发生更新。重新render组件组件又会给hooks传递一个新生成的数组。那么loadProjectList就又会发生改变,所以无限调用就是在这里发生的。
如何解决
直接来是个useMemo依赖于filter,那么返回的数组就不会,在组件重新render的时候重新生成了。就不会出现这样的问题了。