为啥我能够有条件地以一种方式调用钩子,而不能以另一种方式调用?
Posted
技术标签:
【中文标题】为啥我能够有条件地以一种方式调用钩子,而不能以另一种方式调用?【英文标题】:Why am I able to conditionally call a hook one way, but not the other?为什么我能够有条件地以一种方式调用钩子,而不能以另一种方式调用? 【发布时间】:2020-04-03 18:35:19 【问题描述】:背景: 当我刷新仪表板时,useHasPermission 会进行异步调用以确定 用户有权访问 somePermission。
问题: hasPermission 最初评估为 false,但一旦异步调用完成,hasPermission 评估为 true。 这会导致 useQuery、Apollo 钩子在第一次渲染时不被调用,然后在第二次渲染时被调用。 显示以下错误:
“比上一次渲染时渲染了更多的钩子。”
问题: 为什么这个错误只发生在示例 A 而不是示例 B?
// Example A: Does not work
const Dashboard = () =>
const hasPermission = useHasPermission([somePermission]);
const getDashboardData = () =>
const loading, data, error = useQuery(SOME_QUERY,
variables: ...someVars
);
return <Table =data loading=loading error=error><Table>
;
return (
hasPermission ? getDashboardData() : null
<Announcements></Announcements>
)
// Example B: Works
const Dashboard = () =>
const hasPermission = useHasPermission([somePermission]);
const DashboardData = () =>
const loading, data, error = useQuery(ACCOUNTS_FOR_CUSTOMER_DASHBOARD,
variables: ...someVars
);
return <Table =data loading=loading error=error><Table>
;
return (
hasPermission ? (
<DashboardData></DashboardData>
) : null
<Announcements></Announcements>
)
【问题讨论】:
【参考方案1】:Hooks 并不是conditionally used。
在第一个示例中,您有条件地调用了一个使用新钩子并返回 JSX 的函数,因此这违反了钩子的规则。
在第二个示例中,您将创建一个有条件地挂载的新组件DashboardData
。因此,因为它是一个新组件,所以它是允许的。
所以两者的区别在于“A”中useQuery
属于Dashboard
组件,而“B”中属于DashboardData
。
【讨论】:
以上是关于为啥我能够有条件地以一种方式调用钩子,而不能以另一种方式调用?的主要内容,如果未能解决你的问题,请参考以下文章