使用 useEffect 渲染的钩子比上一次渲染时更多
Posted
技术标签:
【中文标题】使用 useEffect 渲染的钩子比上一次渲染时更多【英文标题】:Rendered more hooks than during the previous render using useEffect 【发布时间】:2021-01-06 08:53:50 【问题描述】:我有一个包含对象数组的组件,其中我基于字符串进行过滤。 问题是当我尝试将此过滤器的返回设置为本地状态时,它会抛出我不太理解原因的错误。
import React, useState, useEffect from 'react';
import useQuery from '@apollo/react-hooks';
import gql from 'graphql-tag'
const ProductsGrid = () =>
const [productsList, setProductsList] = useState([]);
const loading, data = useQuery(GET_PRODUCTS);
if (loading) return <div><h4>bla bla bla</h4></div>
const merchants = data;
let filtered = [];
merchants.map(merchant =>
merchant.products.map(product =>
if (product.name.includes('Polo'))
filtered.push(product);
)
)
console.log( filtered );
这是打印以下内容:
所以,因为我想要这个数组处于我的状态,所以我决定这样做:setProductsList(filtered);
插入这一行后发生的事情是这样的:
它开始多次渲染。我假设,每次状态更改时,它都会重新渲染组件(如果我错了,请纠正我)。我不知道为什么它会多次这样做。
所以,我想在这里使用 useEffect 来实现预期的行为。
useEffect(() =>
console.log('useeffect', data);
if (data)
const merchants = data;
console.log(merchants )
let filtered = [];
merchants.map(merchant =>
merchant.products.map(product =>
if (product.name.includes('Polo'))
filtered.push(product);
// console.log( filtered );
)
)
console.log( filtered );
setProductsList(filtered);
,[数据])
输出是:
所以,我了解这里发生了什么以及最后一个错误是什么。
我假设我的方法是朝着正确的方向,使用useEffect
只运行一次函数。
【问题讨论】:
显示完整的组件代码。 @adel 这是完整的代码。除了你在这里看到的,只有一个无关紧要的 return abc。 您的问题可能包含完整的代码,但它是零碎的 - 我们不知道useEffect
如何适合其他所有内容。如果您可以展示完整的组件,或者至少展示足够多的组件,这样我们就可以在原地看到所有钩子的使用情况,这将很有帮助。
@backtick jsfiddle.net/4v2u10yr/1 整个组件脚本在这里。
【参考方案1】:
您的问题是由于useEffect
调用发生在if (loading)
条件之后,该条件提前返回。
在条件返回语句之后调用钩子是非法的,因为它违反了在每次渲染时总是以完全相同的顺序调用钩子的保证。
const loading, data = useQuery(GET_PRODUCTS);
const [productsList, setProductsList] = useState([]);
if (loading)
return (
<div>
<h4>bla bla bla</h4>
</div>
); // <-- Cannot use hooks after this point
useEffect(/* ... */)
要解决此问题,请将 useEffect
调用移到条件之前。
【讨论】:
以上是关于使用 useEffect 渲染的钩子比上一次渲染时更多的主要内容,如果未能解决你的问题,请参考以下文章