api React 中的数据获取最佳实践
api data fetching best practice in react
场景:
我有两个 api 调用,它们都对同一个状态起作用,所以我最初所做的只是在同一个 useEffect 中等待两个 api 调用。但是,其中一个是相当慢的,所以我需要等待很长时间才能呈现页面。
const [loading, setLoading] = useState(true)
useEffect(async() => {
try{
slow_api_call_promise = await slow_api_call
quick_api_call_promise = await quick_api_call
setLoading(false)
let newState = quick_api_call_promise.data.merge(slow_api_call_promise.data)
setState(newState)
}catch(e){
setLoading(false)
//show error message
}
},[])
return <React.Fragment>
{loading ? <SpinnerComponent />: <Actual Page />}
</React.Fragment>
幸运的是,快的实际上提供了我初始渲染所需的大部分状态,而慢的只提供了部分页面状态。所以为了渲染体验,我把他们分成了两个useEffect,分别给他们设置了不同的加载状态。它似乎工作。但这对我来说看起来很傻,它会渲染两次。有没有更好的方法,优化的方法来解决这个问题。
const [loadingWhole, setLoadingWhole] = useState(true)
const [loadingPart, setLoadingPart] = useState(true)
useEffect(async() => {
quick_api_call_promise = await quick_api_call
setLoadingWhole(false)
},[])
useEffect(async() => {
slow_api_call_promise = await slow_api_call
setLoadingPart(false)
},[])
是的,你可以保留一个效果,在你获取快速响应后先做一个setState
:
const [state, setState] = useState(null);
const [loadingWhole, setLoadingWhole] = useState(true);
const [loadingPart, setLoadingPart] = useState(true);
async function fetchResults() {
const quickResult = await callQuickApi();
setState(quickResult.data);
setLoadingPart(false);
const slowResult = await callSlowApi();
let newState = merge(quickResult.data, slowResult.data);
setState(newState);
setLoadingWhole(false);
}
useEffect(async() => {
fetchResults().catch(err => {
setLoadingPart(false);
setLoadingWhole(false);
//show error message
});
},[]);
顺便说一句,您可能想考虑只使用一个而不是 4 个单独的 useState
挂钩,它只能处于 5 种状态,而不是多种组合(甚至 !loadingWhole && loadingPart
感):
- 加载中
- 错误
- 部分响应 + 加载
- 部分响应 + 错误
- 完全响应
场景:
我有两个 api 调用,它们都对同一个状态起作用,所以我最初所做的只是在同一个 useEffect 中等待两个 api 调用。但是,其中一个是相当慢的,所以我需要等待很长时间才能呈现页面。
const [loading, setLoading] = useState(true)
useEffect(async() => {
try{
slow_api_call_promise = await slow_api_call
quick_api_call_promise = await quick_api_call
setLoading(false)
let newState = quick_api_call_promise.data.merge(slow_api_call_promise.data)
setState(newState)
}catch(e){
setLoading(false)
//show error message
}
},[])
return <React.Fragment>
{loading ? <SpinnerComponent />: <Actual Page />}
</React.Fragment>
幸运的是,快的实际上提供了我初始渲染所需的大部分状态,而慢的只提供了部分页面状态。所以为了渲染体验,我把他们分成了两个useEffect,分别给他们设置了不同的加载状态。它似乎工作。但这对我来说看起来很傻,它会渲染两次。有没有更好的方法,优化的方法来解决这个问题。
const [loadingWhole, setLoadingWhole] = useState(true)
const [loadingPart, setLoadingPart] = useState(true)
useEffect(async() => {
quick_api_call_promise = await quick_api_call
setLoadingWhole(false)
},[])
useEffect(async() => {
slow_api_call_promise = await slow_api_call
setLoadingPart(false)
},[])
是的,你可以保留一个效果,在你获取快速响应后先做一个setState
:
const [state, setState] = useState(null);
const [loadingWhole, setLoadingWhole] = useState(true);
const [loadingPart, setLoadingPart] = useState(true);
async function fetchResults() {
const quickResult = await callQuickApi();
setState(quickResult.data);
setLoadingPart(false);
const slowResult = await callSlowApi();
let newState = merge(quickResult.data, slowResult.data);
setState(newState);
setLoadingWhole(false);
}
useEffect(async() => {
fetchResults().catch(err => {
setLoadingPart(false);
setLoadingWhole(false);
//show error message
});
},[]);
顺便说一句,您可能想考虑只使用一个而不是 4 个单独的 useState
挂钩,它只能处于 5 种状态,而不是多种组合(甚至 !loadingWhole && loadingPart
感):
- 加载中
- 错误
- 部分响应 + 加载
- 部分响应 + 错误
- 完全响应