简体   繁体   English

返回结果时先渲染组件

[英]Render components before others when results are returned

I have a function that fetches from an API with four endpoints;我有一个 function,它从具有四个端点的 API 中获取; one that returns the data (from another API) and three others that do some analysis on text.一个返回数据(从另一个 API),另外三个对文本进行一些分析。 I first call the first endpoint (/getdata), which returns the data plus a cleaned text attribute.我首先调用第一个端点 (/getdata),它返回数据和经过清理的文本属性。 I then use the clean text to call the other three endpoints.然后我使用干净的文本调用其他三个端点。

My problem is, the three analysis calls take considerably more time to complete.我的问题是,这三个分析调用需要相当多的时间才能完成。 I want to fetch the data, display all components related to the data only (no analysis), then after the other 3 calls complete (there will be an indication like a loading animation on the components, etc. if possible), the components related to them are populated.我想获取数据,只显示与数据相关的所有组件(不分析),然后在其他 3 个调用完成后(如果可能的话,组件上会有加载 animation 等指示),组件相关对他们来说人口稠密。

What I have:我拥有的:

// this is set through a form
const [text, setText] = useState('');

const getData = useCallback(async () => {
    const url = `https://my-api.com/api/getdata?text=${text}`;
    console.log(url);
    const response = await fetch(url);
    const data = await response.json();

    return data;
}, [text]);

const getOtherData = async (data) => {
    const newData = [];
    for (const tweet of data.results) {
      const url1 = `https://my-api.com/api/getsentiment?text=${tweet.clean_text}`;
      const url2 = `https://my-api.com/api/getkeywords?text=${tweet.clean_text}`;
      const url2 = `https://my-api.com/api/gettopics?text=${tweet.clean_text}`;

      const [sentiment, keywords, topic] = await Promise.all([
        await fetch(url1).then((res) => res.json()),
        await fetch(url2).then((res) => res.json()),
        await fetch(url3).then((res) => res.json()),
      ]);

      tweet['sentiment'] = sentiment.sentiment;
      tweet['keywords'] = keywords.keywords;
      tweet['topic'] = topic.topics;

      newData.push(tweet);
    }

    return newData;
};

const handleSubmit = async () => {
    ...
    setLoading(true);

    const data = await getData(); // this is the raw data plus cleaned text

    const newData = await getOtherData(data);
    setData(newData);

    setLoading(false);
};

I could probably setData after getting the data without the text analysis, but I'm not sure how to later update the other components with the new analyzed data.在没有文本分析的情况下获取数据后,我可能可以设置数据,但我setData以后如何用新分析的数据更新其他组件。 Setting the data again would cause everything to update/reload, right?再次设置数据会导致所有内容更新/重新加载,对吗? I thought of separating the state for each;我想把每个 state 分开; one with the raw data (and cleaned text) only, and another with the raw data + text analysis results.一个只包含原始数据(和清理过的文本),另一个包含原始数据+文本分析结果。 Does that make sense or is there a better way?这有意义还是有更好的方法?

You can use useEffect() .您可以使用useEffect() Eg:例如:

(This example is to be understood as an illustration of the principle. This is very likely not the optimal approach, or might even not work at all for your use case. Eg it would fail if data can change independent of these loading calls, or eg the loading state might be unnecessary if data can never change outside of these loading calls. You also might want to consider to use two useEffect() blocks and custom hooks ) (这个例子应该被理解为原理的说明。这很可能不是最佳方法,或者甚至可能根本不适用于您的用例。例如,如果数据可以独立于这些加载调用而改变,它将失败,或者例如,如果数据永远不会在这些加载调用之外更改,则loading state 可能是不必要的。您可能还需要考虑使用两个useEffect()块和自定义挂钩

useEffect( () => {

  if( !data && !loading ){   // <-- some condition to check if data is loaded
     setLoading( true );
     getData().then( firstData => {
       setLoading( false );
       setData( firstData );
     });

  } else if( !data.containsNewData && !loading ) { // <-- some condition to check for new data
     setLoading( true );
     getOtherData( data ).then( newData => {
       setLoading( false );
       setData( newData );
     });

  } else {
     // all data is available
  }
}, [ data ]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM