我正在使用NextJS的useRouter
来访问路由器,如下所示:
const router = useRouter();
但是,当我渲染组件时,我倾向于注意到router
在实际实例化之前可以是null
。我的解决方法是做这样的事情:
const router = useRouter();
if (!router) return null;
return (
// ... jsx
);
但是,我有一个正在使用的自定义钩子,它取决于路由器的查询:
const router = useRouter();
if (!router) return null;
const {data} = useCustomHook(router.query.id);
return ( //.... )
但是我收到了这样的错误提示:
React Hook "useCustomHook" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?
我的解决方法是使两个单独的组件来处理此条件:
const HookComponent = ({ id }) => {
const { data } = useCustomHook(id);
return ( // ....)
}
const HookComponentWrapper = () => {
const router = useRouter();
if (!router) return null;
return <HookComponent id={router.query.id}/>
}
我的问题是:是否有可能避免仅为条件而添加该包装?
这样的事情?
const router = useRouter();
const {data} = useCustomHook(router && router.query && router.query.id); // handle null case inside custom hook
if (!router) return null;
由于router
有时可以为null,因此您可以使用保护子句来访问传递给该挂钩的id。 useCustomHook
仍然需要优雅地处理空输入。
const {data} = useCustomHook(router && router.query && router.query.id);
或在构建允许的情况下使用optional chaining
const {data} = useCustomHook(router?.query?.id);
此时,我建议只传递router
对象,并在任何自定义钩子中处理从中提取所需的内容。