渲染的钩子比上一次渲染时更多

Posted

技术标签:

【中文标题】渲染的钩子比上一次渲染时更多【英文标题】:Rendered more hooks than during the previous render 【发布时间】:2019-12-24 21:16:43 【问题描述】:

如何使用带有 react-apollo-hooks 的 2 个 graphql 查询,其中第二个查询取决于从第一个查询中检索到的参数?

我尝试使用如下所示的 2 个查询:

const [o, setO] = useState()

const  loading: loadingO, error: errorO, data: dataO  = useQuery(Q_GET_O,  onCompleted: d => setO(d.getO[0].id) );

if (loadingO)  return "error" 

const  loading: loadingOP, error: errorOP, data: dataOP  = useQuery(Q_GET_OP,  variables:  o  )

但是,当我运行我的项目时,react-hooks 会给我以下消息:

"index.js:1437 警告:React 检测到 Upgrade 调用 Hooks 的顺序发生了变化。如果不修复,这将导致错误和错误。有关更多信息,请阅读 Hooks 规则"

我想知道如何使用 react-apollo-hooks 来运行依赖于另一个查询的查询。如果预先知道 graphql 查询变量,它会很好用。但是,对于来自其他查询的变量,我没有找到解决方案。

【问题讨论】:

【参考方案1】:

这里的问题是,在所有钩子有机会运行之前,您已经短路返回。

如果你在所有钩子有机会被调用之前退出渲染函数,React 会报错。

例如:

function BrokenFoo () 
  const query = useSomeQuery();
  if (query.loading) return <Loading />

  // This will cause some issues because 
  // it's possible that we return before our useState hook gets called

  const [bar, setBar] = useState();

  return <SomeComponent bar=bar setBar=setBar data=query.data />

修复:

function FixedFoo () 
  // This will be fine because 
  // all of the hooks have a chance to be called before a return
  const query = useSomeQuery();
  const [bar, setBar] = useState();

  if (query.loading) return <Loading />

  return <SomeComponent bar=bar setBar=setBar data=query.data />

【讨论】:

很高兴能帮上忙!【参考方案2】:

您可以在第二个查询中添加skip 选项并丢失if 条件:

const  loading: loadingOP, error: errorOP, data: dataOP  
    = useQuery(Q_GET_OP,  variables:  o , skip: !o  )

来自文档: If skip is true, the query will be skipped entirely

【讨论】:

仅供参考:似乎更依赖于使用 loadingOP 来检查是否跳过查询。

以上是关于渲染的钩子比上一次渲染时更多的主要内容,如果未能解决你的问题,请参考以下文章

React Hooks 渲染的钩子比上一次渲染时更多

React - 出现“渲染的钩子比上一次渲染时更多”错误

使用 useEffect 渲染的钩子比上一次渲染时更多

Uncaught Invariant Violation:渲染的钩子比上一次渲染时更多

Next.JS“比上一次渲染时渲染了更多的钩子”

当钩子的初始值是来自数据库的查询结果时,“比上一次渲染期间渲染的钩子更多”错误