首页 > 解决方案 > 在使用 graphql 的 useQuery 获取的数据更新 useEffect 钩子内的状态变量时防止无限渲染

问题描述

Graphql 提供了 useQuery 钩子来获取数据。每当组件重新渲染时,它都会被调用。

//mocking useQuery hook of graphql, which updates the data variable
  const data = useQuery(false);

我正在使用useEffect挂钩来控制调用“useQuery”的次数。

我想要做的是每当我从 useQuery 接收数据时,我想对数据执行一些操作并将其设置为另一个状态变量“ stateOfValue ”,它是一个嵌套对象数据。所以这必须在 useEffect 挂钩内完成。

因此,我需要添加我的stateOfValue和“ data ”(这有我的 API 数据)变量作为 useEffect 挂钩的依赖项。

  const [stateOfValue, setStateOfValue] = useState({
    name: "jack",
    options: []
  });

  const someOperation = (currentState) => {
    return {
        ...currentState,
        options: [1, 2, 3]
      };
  }
  useEffect(() => {
    if (data) {
      let newValue = someOperation(stateOfValue);
      setStateOfValue(newValue);
    }
  }, [data, stateOfValue]);

基本上,我将在我的 useEffect 中使用的所有变量添加为依赖项,因为根据 Dan Abramov,这是正确的做法。

现在,根据反应,状态更新必须在没有突变的情况下完成,因为我每次需要更新状态时都会创建一个新对象。但是通过设置一个新的状态变量对象,我的组件被重新渲染,导致无限渲染。

如何以这样一种方式实现它,即我将所有变量传递给我的 useEffect 依赖数组,并让它只执行一次 useEffect。

请注意:如果我不将stateOfValue变量添加到依赖项中,它会起作用,但那将是在撒谎。

这是复制的链接。

标签: reactjsgraphqlreact-hooksreact-apollo

解决方案


我认为您误解了您想要在依赖项数组中的内容[data, setStateOfValue]不是[data, stateOfValue]. 因为你使用setStateOfValuenot stateOfValueinsideuseEffect 正确的是:

const [stateOfValue, setStateOfValue] = useState({
    name: "jack",
    options: []
  });

  const someOperation = useCallback((prevValue) => {
    return {
        ...prevValue,
        options: [1, 2, 3]
      };
  },[])
  useEffect(() => {
    if (data) {
      setStateOfValue(prevValue => {
        let newValue = someOperation(prevValue);
        return newValue
      });
    }
  }, [data, setStateOfValue,someOperation]);

推荐阅读