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感):

  • 加载中
  • 错误
  • 部分响应 + 加载
  • 部分响应 + 错误
  • 完全响应