我有一个带有对象数组的组件,除其他外,我正在基于字符串进行过滤。 问题是,当我尝试将此过滤器的返回值设置为本地状态时,会抛出我不太了解原因的错误。
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
仅运行一次函数。
答案 0 :(得分:0)
您的问题是由于在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
调用移到条件调用之前。