Nextjs throws React检测到Hooks的顺序发生了变化,即使是从顶级调用开始



我正在使用SWR从数据库中获取一些数据,但收到以下错误消息:

Warning: React has detected a change in the order of Hooks called by OrganizationSettings. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks

Previous render            Next render
------------------------------------------------------
1. useContext                 useContext
2. useRef                     useRef
3. useRef                     useRef
4. useRef                     useRef
5. useRef                     useRef
6. useRef                     useRef
7. useRef                     useRef
8. useMemo                    useMemo
9. useCallback                useCallback
10. useSyncExternalStore      useSyncExternalStore
11. useRef                    useRef
12. useCallback               useCallback
13. useCallback               useCallback
14. useLayoutEffect           useLayoutEffect
15. useLayoutEffect           useLayoutEffect
16. useLayoutEffect           useLayoutEffect
17. useDebugValue             useDebugValue
18. undefined                 useContext
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
at OrganizationSettings (webpack-internal:///./components/organization/OrganizationSettings.tsx:21:86)
at SettingsPage
at section

尽管如此,我还是认为我应该只在顶级和功能组件中调用钩子。检查我的代码:

const OrganizationSettings = () => {
const { data, isLoading, isError } = useOrganization();
if (isError) return <LoadingError />;
if (isLoading) return <LoadingSpinner />; 
return (
<Box bg={useColorModeValue('gray.50', 'inherit')} p={10} borderRadius="lg">
<Box mt={[10, 0]}>
{/* Commented out for readability */}
</Box>
</Box>
);
};
export default OrganizationSettings;

根据错误,它在if (isLoading) return <LoadingSpinner />;之后的线路21之后失败

你知道我做错了什么或错过了什么吗?这没有意义,因为应用程序也运行良好,而且我确实收到了数据+应用程序渲染正确。

这是因为您在渲染中直接使用了钩子,而且有时不会根据上述条件对其进行渲染。

错误消息只显示内置挂钩,所以这就是为什么您看到列出的是useContext而不是useColorModeValue,但在这个挂钩下面必须使用上下文。

正是由于这个原因,以这种方式使用钩子是一种糟糕的做法。它运行良好,但仅在特定条件下运行,这会使代码不稳定。

将钩子移到任何可能的return语句上方。

const OrganizationSettings = () => {
const bg = useColorModeValue('gray.50', 'inherit');
const { data, isLoading, isError } = useOrganization();
if (isError) return <LoadingError />;
if (isLoading) return <LoadingSpinner />; 
return (
<Box bg={bg} p={10} borderRadius="lg">
<Box mt={[10, 0]}>
{/* Commented out for readability */}
</Box>
</Box>
);
};

相关内容

最新更新