【发布时间】:2021-03-21 14:35:41
【问题描述】:
我有一个可以像这样使用的 HTTP 钩子:
const { data, error, isLoading, executeFetch } = useHttp<IArticle[]>('news', []);
在同一个组件中,我想触发另一个 API 调用来 POST 数据并更新其中一篇文章:
const handleChange = (article: IArticle, event: React.ChangeEvent<HTMLInputElement>) => {
executeFetch(`updateNews?id=${article.id}`, { method: 'post', data: { isRead: event.target.checked }});
};
return (
<>
<div className={classes.articleListHeader}>
<h1>Article List</h1>
<small className={classes.headerSubtitle}>{data.length} Articles</small>
</div>
<ul>
{data.map(article => <Article key={article.id} article={article} handleChange={handleChange}/>)}
</ul>
</>
)
我用来获取数据的自定义钩子:
export function useHttp<T>(initUrl: string, initData: T): UseHttp<T> {
const initOptions: AxiosRequestConfig = { url: initUrl };
const [options, setOptions] = useState(initOptions);
const useHttpReducer = createHttpReducer<T>();
const [state, dispatch] = useReducer(useHttpReducer, {
isLoading: false,
error: '',
data: initData
});
useEffect(() => {
let cancelRequest = false;
const fetchData = async (cancelRequest: boolean = false) => {
if (!options.url) return;
dispatch({ type: API_REQUEST});
try {
const responsePromise: AxiosPromise<T> = axios(options);
const response = await responsePromise;
if (cancelRequest) return;
dispatch({ type: API_SUCCESS, payload: response.data });
} catch (e) {
console.log("Got error", e);
dispatch({ type: API_ERROR, payload: e.message });
}
};
fetchData(cancelRequest);
return () => {
cancelRequest = true;
}
}, [options]);
const executeFetch = (url: string, options: AxiosRequestConfig = axiosInitialOptions): void => {
options.url = url;
setOptions(options);
};
return { ...state, executeFetch}
问题是,当我做这样的事情时,data 替换为新的响应(POST 请求),然后我的 UI 崩溃(没有更多的文章列表..)
当我需要在同一个组件中调用另一个 API 并同时保持 HTTP 挂钩的可重用性时,管理此类情况的最佳做法是什么?
我只是想在我的 GET 请求之后在组件中的某处执行 POST 请求 - 如何以可重用的方式执行它并解决我的问题?
【问题讨论】:
-
不确定这是否会有所帮助,但您是否查看了 Vercel 的 useSWR?
-
谢谢,但我想学习:D
-
executeFetch是在组件内部定义的函数吗?如果是,你能添加它的实现吗?现在,我不明白为什么data的值会改变。 -
@Eldraxm
executeFetch函数是从 useHttp 钩子返回的。 -
可以重命名两次调用中数据的返回值。示例: const { data: firstAPICall, error: firstError } = useHttp
('news', []); const { 数据:secondAPICall,错误:secondError} = useHttp ('news', []);
标签: javascript reactjs