在一个函数组件加载的时候报错:
Uncaught Invariant Violation: Rendered more hooks than during the previous render.
翻译一下的意思是: 比上次渲染时渲染了更多的钩子。 下面是报错后的一段提示
react-dom.development.js?61bb:506 Warning: React has detected a change in the order of Hooks called by ReportEditor. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks
Previous render Next render
------------------------------------------------------
1. useContext useContext
2. useEffect useEffect
3. useContext useContext
4. useEffect useEffect
5. useContext useContext
6. useEffect useEffect
7. useContext useContext
8. useEffect useEffect
9. useContext useContext
10. useEffect useEffect
11. useContext useContext
12. useEffect useEffect
13. useContext useContext
14. useEffect useEffect
15. useContext useContext
16. useEffect useEffect
17. useContext useContext
18. useRef useRef
19. useEffect useEffect
20. useContext useContext
21. useReducer useReducer
22. useMemo useMemo
23. useRef useRef
24. useRef useRef
25. useRef useRef
26. useLayoutEffect useLayoutEffect
27. useLayoutEffect useLayoutEffect
28. useContext useContext
29. useReducer useReducer
30. useMemo useMemo
31. useRef useRef
32. useRef useRef
33. useRef useRef
34. useLayoutEffect useLayoutEffect
35. useLayoutEffect useLayoutEffect
36. useContext useContext
37. useReducer useReducer
38. useMemo useMemo
39. useRef useRef
40. useRef useRef
41. useRef useRef
42. useLayoutEffect useLayoutEffect
43. useLayoutEffect useLayoutEffect
44. undefined useCallback
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
结合代码想到可能是因为提前返回造成的两次绑定的usecallback数量不一致,下面是代码
useEffect(() => {
dispatch(ReportActions.getReportConfig(reportId))
}, [])
const currentReport = useSelector(makeSelectCurrentDisplay())
const currentLayerList = useSelector(makeSelectCurrentLayerList())
const layersOperationInfo = useSelector(makeSelectCurrentLayersOperationInfo())
if(!currentReport){
return <></>
}
const commandLayers = useCallback((operation) => {
...
}, [])
const selectionChange = useCallback(
(layerId: number, checked: boolean, exclusive: boolean) => {
.....
},
[]
)
return (
<div style={{ position: 'fixed', top: 48, bottom: 0, left: 0, right: 0, display: 'flex' }}>
<ReportAdaptor>
....
</Layout>
</ReportAdaptor>
</div>
)
}
因为通过
if(!currentReport){
return <>
}
这句代码执行的时候提前返回了,导致第一次执行没有执行后面的usecallback
,第二次执行的时候有callback
,两次callback
数量不一致导致了这个错误,后面把currentReport
是否为空的判断放在return之前&&usecallback
定义之后就可以了。