[英]Render components before others when results are returned
我有一个 function,它从具有四个端点的 API 中获取; 一个返回数据(从另一个 API),另外三个对文本进行一些分析。 我首先调用第一个端点 (/getdata),它返回数据和经过清理的文本属性。 然后我使用干净的文本调用其他三个端点。
我的问题是,这三个分析调用需要相当多的时间才能完成。 我想获取数据,只显示与数据相关的所有组件(不分析),然后在其他 3 个调用完成后(如果可能的话,组件上会有加载 animation 等指示),组件相关对他们来说人口稠密。
我拥有的:
// 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);
};
在没有文本分析的情况下获取数据后,我可能可以设置数据,但我setData
以后如何用新分析的数据更新其他组件。 再次设置数据会导致所有内容更新/重新加载,对吗? 我想把每个 state 分开; 一个只包含原始数据(和清理过的文本),另一个包含原始数据+文本分析结果。 这有意义还是有更好的方法?
您可以使用useEffect()
。 例如:
(这个例子应该被理解为原理的说明。这很可能不是最佳方法,或者甚至可能根本不适用于您的用例。例如,如果数据可以独立于这些加载调用而改变,它将失败,或者例如,如果数据永远不会在这些加载调用之外更改,则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.