我有一个 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>
);
};
``
答案 0 :(得分:0)
我确定您应该看到有关在回调中调用 useState
React 钩子的 linting 错误,这违反了钩子规则。此外,传递给 results
的 Child
是未定义的,因为它仅在 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>
);
};