reactjs - 使用 GraphQL 在 NextJS 中渲染的钩子比上一次渲染时更多
问题描述
我将导航栏放在我的 _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)
解决方案
正如@xadmn 所提到的,您正在有条件地渲染您的钩子,而 React 期望每次渲染时都有相同数量的钩子调用,从而违反了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
)
}
推荐阅读
- sqlite - 如何找到所需的条款条目
- mysql - MySQL:是否可以使用 SELECT 作为唯一权限在 SELECT 之外设置变量?
- linux - 如何生成数字 X 到给定数字 Y 的多重性的随机列表?
- python - 如何删除熊猫数据框列中与另一列中的单词匹配的单词
- python - 如何在数据框的列中查找元素的编号
- android - Firebase Facebook 登录,即使在卸载应用程序后清除缓存和注销
- ios - 如何删除黄色选择突出显示?
- html - 在 HTML5 中使用正则表达式限制数字模式中的年份
- java - 快速排序:更改枢轴元素会导致 StackOverflow
- python - 合并以这种格式 XXXXX.csv.gz_1_2.tar 和 XXXXX.csv.gz_2_2.tar 分块的两个文件(使用 python 或 pyspark)