【问题标题】:Rendered more hooks than during the previous render in NextJS using GraphQL使用 GraphQL 在 NextJS 中渲染的钩子比上一次渲染时更多
【发布时间】:2021-04-29 13:17:30
【问题描述】:

我将导航栏放在我的 _app.js 中,所以我不需要在每个组件中都插入它。我的问题是,在我登录后它会输出错误Rendered more hooks than during the previous render. 并将其指向useQuery(GETCARTDATA

请在此处检查我的代码

const App = ({ Component, pageProps }) => {
    const token = getToken()
    const [isPopUpShow, setPopUpShow] = useState(false)
    const [cartStateData, setCartStateData] = useState([])
    const [isCartOpen, setCartOpen] = useState(false)
    let cartDetailsData
    
    if (token) {
      // eslint-disable-next-line react-hooks/rules-of-hooks
      cartDetailsData = useLazyQuery(GETCARTDATA, {
        variables: {
          page: 1
        },
      })
      // eslint-disable-next-line react-hooks/rules-of-hooks
      useMemo(() => {
        const cartData = get(cartDetailsData.data, 'findCartDetails.orders') || []
        const cartItems = []
        if (cartData.length) {
          cartData.map(
            itm =>
              itm.lineItems.length &&
              itm.lineItems.map(item => cartItems.push(item))
          )
        }
        setCartStateData(cartItems)
      }, [cartDetailsData.data])
    }
  
    return (
      <>
        <div className="app-outer">
          {token ? (
            <ShowroomHeader
              isPopUpShow={isPopUpShow}
              setPopUpShow={setPopUpShow}
              cartStateData={cartStateData}
              cartDetailsData={cartDetailsData}
              token={token}
            />
          ) : (
            <Navbar />
          )}
        </div>
  
        <div className="main">
          <Component {...pageProps} />
        </div>

      </>
    )
  }
  
  export default withApollo(App)

【问题讨论】:

  • 钩子规则被破坏 - 你不能有条件地使用钩子......改用useLazyQuery(和效果)
  • 显示方法,更新 q。
  • @xadm。已更新。
  • 从简单的实时 (CRA) 反应(不是下一步)开始,然后按照教程进行操作,在您确切知道自己在做什么以及为什么要这样做时编写代码 ... at至少对于基本的反应事物......使用 FC 和钩子需要不同的(而不是“线性”)思维

标签: reactjs react-hooks graphql next.js apollo


【解决方案1】:

作为@xadmn mentioned,您正在有条件地渲染您的钩子,而 React 期望每次渲染时的钩子调用数量相同,从而破坏了rules of Hooks

您需要删除 if 语句并将条件移动到 useEffect 挂钩中,使用 useLazyQuery 的返回函数从那里执行查询。您还可以将 useMemo 代码移动到 onCompleted 回调,因为它取决于查询的结果。

const App = ({ Component, pageProps }) => {
    const token = getToken()
    const [isPopUpShow, setPopUpShow] = useState(false)
    const [cartStateData, setCartStateData] = useState([])
    const [isCartOpen, setCartOpen] = useState(false)

    const [getCardData, cartDetailsData] = useLazyQuery(GETCARTDATA, {
        onCompleted: (data) => {
            const cartData = get(data, 'findCartDetails.orders') || []
            const cartItems = []
            if (cartData.length) {
                cartData.map(
                    itm =>
                        itm.lineItems.length &&
                        itm.lineItems.map(item => cartItems.push(item))
                )
            }
            setCartStateData(cartItems)
        }
    })

    useEffect(() => {
        if (token) {
            getCardData({ variables: { page: 1 } })
        }
    }, [token])
  
    return (
        // Your JSX here
    )
}

【讨论】:

    猜你喜欢
    • 2019-12-24
    • 2021-01-06
    • 2021-12-01
    • 2021-05-31
    • 2020-11-26
    • 1970-01-01
    • 2021-11-02
    • 2021-09-29
    • 2021-10-12
    相关资源
    最近更新 更多