Uncaught (in promise) ReferenceError: xxx is not defined in react in useCallBack

时间:2021-06-07 22:41:03

标签: reactjs react-native async-await

我有一个 Home 组件,需要等待 requestQuery api 完成,然后解析响应 data 并将 data 传递给 Child 组件,如下代码所示。如果我将 data 变量移出 useCallBack 并将响应 data 硬编码为模拟数据。我的代码正在工作。但是,在使用异步函数将数据变量移动到 useCallBack 后,出现错误 Uncaught (in promise) ReferenceError: results is not defined 我该如何解决?

import React, {useCallback, FC, useEffect, useState} from 'react';
export const Home: FC = () => {
  const initData = useCallback(async (): Promise<void> => {

      // attempt to load based on flow
  const [hasLoadingFailed, setLoadingFailed] = useState<boolean>(false);
  const [isLoading, setLoading] = useState<boolean>(false);

    try {
      const {data, errors} = await requestQuery({num: 1});

      // if errors or no data, throw error
      if (!data || errors?.length) throw Error('Errors Retrieving Data');

      const {results = []}: QueryResponse = data;
      console.log({results}); //no problem to get results
    } catch {
      setLoadingFailed(true);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    initData();
  }, [initData]);

  return (
    <div><Child data={results} /></div>
  );
};
``

1 个答案:

答案 0 :(得分:0)

问题

我确定您应该看到有关在回调中调用 useState React 钩子的 linting 错误,这违反了钩子规则。此外,传递给 resultsChild 是未定义的,因为它仅在 useCallback 钩子的回调范围内声明,而不是在 Home 组件函数范围内声明。

解决方案

修复 useState 挂钩的问题并声明要传递给子组件的 results 状态。

import React, { useCallback, FC, useEffect, useState } from 'react';

export const Home: FC = () => {
  const [hasLoadingFailed, setLoadingFailed] = useState<boolean>(false);
  const [isLoading, setLoading] = useState<boolean>(false);
  const [results, setResults] = useState<any[]>([]); // <-- default results state

  const initData = useCallback(async (): Promise<void> => {
    setLoading(true);
    try {
      const {data, errors} = await requestQuery({ num: 1 });

      // if errors or no data, throw error
      if (!data || errors?.length) throw Error('Errors Retrieving Data');

      const { results = [] }: QueryResponse = data;
      console.log({ results }); //no problem to get results

      setResults(results); // <-- update the results state
    } catch {
      setLoadingFailed(true);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    initData();
  }, [initData]);

  return (
    <div>
      <Child data={results} />
    </div>
  );
};