const { response, setResponse } = useResponseState();
const handleNext = () => {
if (
response.currentResponse !== undefined &&
response.responses!== undefined
) {
if (response.currentResponse< response.responses.length) {
setResponse({
currentResponse: response.currentResponse + 1,
responses: response.responses,
});
}
}
};
const responseID= response.responses![response.currentResponse!].id ?? 0;
const { data, error } = useFetch<ExampleType>(
`${process.env.REACT_APP_API_ENDPOINT}example/${exampleID}`
);
return error || !data ? (
<>error</>
) : (
<>success</>有人能帮助我理解为什么当handleNext被调用时数据是未定义的。在返回的成功部分中,有一个按钮带有onclick,但我尝试只显示您需要看到的内容。有人能看到这里有什么不对劲吗?
ResponseState是一个上下文。
端点返回的内容如下:
{"id":1,"exampleProp2: "test"}钩子:
import { useEffect, useReducer, useRef, useState } from 'react';
import State from './State';
type Cache<T> = { [url: string]: T };
// discriminated union type
type Action<T> =
| { type: 'loading' }
| { type: 'fetched'; payload: T }
| { type: 'error'; payload: Error };
function useFetch<T = unknown>(url?: string, options?: RequestInit): State<T> {
const cache = useRef<Cache<T>>({});
// Used to prevent state update if the component is unmounted
const cancelRequest = useRef<boolean>(false);
const initialState: State<T> = {
error: undefined,
data: undefined,
};
// Keep state logic separated
const fetchReducer = (state: State<T>, action: Action<T>): State<T> => {
switch (action.type) {
case 'loading':
return { ...initialState };
case 'fetched':
return { ...initialState, data: action.payload };
case 'error':
return { ...initialState, error: action.payload };
default:
return state;
}
};
const [state, dispatch] = useReducer(fetchReducer, initialState);
useEffect(() => {
// Do nothing if the url is not given
if (!url) return;
const fetchData = async () => {
dispatch({ type: 'loading' });
// If a cache exists for this url, return it
if (cache.current[url]) {
dispatch({ type: 'fetched', payload: cache.current[url] });
return;
}
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(response.statusText);
}
const data = (await response.json()) as T;
cache.current[url] = data;
if (cancelRequest.current) return;
dispatch({ type: 'fetched', payload: data });
} catch (error) {
if (cancelRequest.current) return;
dispatch({ type: 'error', payload: error as Error });
}
};
void fetchData();
// Use the cleanup function for avoiding a possibly...
// ...state update after the component was unmounted
return () => {
cancelRequest.current = true;
};
}, [url]);
return state;
}
export default useFetch;这正是使用的钩子。这里还有什么不管用的吗?
发布于 2022-01-24 13:05:02
我取决于您正在调用的useFetch的API契约是什么(钩子是如何工作的,预期返回值是什么)。但是通常情况下,抓取是一种异步操作,是在后台完成的。数据在第一阶段可以是undefined或null,因为没有发送请求或没有收到响应。
假设钩子返回以下内容- { data, error, loading, requested }。返回值可以如下:
{ loading: false, requested: false } (在您的情况下不太可能){ loading: true, requested: true }{ loading: false, requested: true, data: {} }{ loading: false, requested: true, error: {} }如您所见,只有一种状态可以预期数据是可用的。这只是一个理论上的阐述,因为您还没有指定足够的useFetch钩子。
例如,您可以使用来自使用-http的钩子。如果您检查了文档,那么您应该注意到,它们建议按照自己的值初始化数据,以避免undefined。在你的例子中,它应该是这样的:
const url = `${process.env.REACT_APP_API_ENDPOINT}example/${exampleID}`
const { data = {}, error, loading } = useFetch < ExampleType > (url);
return loading ? (
<>Loading...</>
) : error ? (
<>Failure: ${JSON.stringify(error)}</>
) : (
<>Success: ${JSON.stringify(data))</>
)您应该明确地检查您正在使用的useFetch<T>文档,它应该在这里编写。
定制钩更新
对于来自指定物品的钩子,您还应该查阅axios反应的文档。它清楚地指出,data存储在这样命名的属性中。这意味着,如果您在文章中复制钩子代码,那么它就无法工作。Promise.then的处理程序没有一部分使用该值:
//checking for multiple responses for more flexibility
//with the url we send in.
res.data.content && setData(res.data.content);
res.content && setData(res.content);为了正确访问响应数据,必须对其进行修复,例如:
// Give up the flexibility
setData(rest.?data)
// Keep some flexibility
// ... but you have to define data acquisition algorithm
// const data = res.content || rest.data
// setData(data)https://stackoverflow.com/questions/70832816
复制相似问题