使用 GraphQL 在 NextJS 中呈现比之前呈现更多的钩子
Rendered more hooks than during the previous render in NextJS using GraphQL
我将导航栏放在 _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)
如, you're rendering your hooks conditionally while React expects the same number of hook calls on every render, thus breaking the 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
)
}
我将导航栏放在 _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)
如
您需要删除 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
)
}