React中如何處理承諾demo
正文
諾言本質(zhì)上是一種處理異步操作的方式,一個常見的例子是在React中執(zhí)行API請求。為了在React生命周期中使用這些操作,我們可以使用useState鉤子來存儲承諾的結(jié)果,當(dāng)它被解決并重新渲染組件。
本教程假設(shè)你熟悉React中鉤子的使用,所以如果你不確定,請查看我們的介紹
什么是 "承諾"?
諾言允許你在JavaScript中執(zhí)行異步操作。要從頭開始構(gòu)建一個Promise,你可以使用Promise構(gòu)造器。這個函數(shù)需要兩個參數(shù):"resolve",當(dāng)操作完成時調(diào)用的函數(shù),以及 "reject",當(dāng)操作失敗時調(diào)用的函數(shù)。然后,當(dāng)你的操作完成時,你必須調(diào)用這些函數(shù)中的一個。
JavaScript給了你兩種處理承諾結(jié)果的方法,第一種是 .then(),一個以函數(shù)為參數(shù)的函數(shù),它將把解決后的值傳遞給該函數(shù):
const promiseThen = new Promise((resolve, reject) => { setTimeout(() => { resolve('Hi!'); }, 1000); }); promiseThen .then((val) => { console.log(val); }) .catch((err) => console.log(err));
其他的東西都不會等待你的承諾解決,但是你提供給 ***.then()***將在承諾解析時運(yùn)行。
另一種方法是 "async/await "功能,這通常是首選;如果你 "等待 "一個承諾,代碼將停止運(yùn)行,直到承諾完成。下面是上面的例子,重寫后使用了await來代替:
const promiseAwait = new Promise((resolve, reject) => { setTimeout(() => { resolve('Hi!'); }, 1000); }); const result = await promiseAwait; console.log(result);
在React的頁面加載中使用承諾
要在React中使用一個Promise的值,你可以使用一個 ***useEffect()***鉤子,用一個空的依賴數(shù)組來等待承諾的解析,并將結(jié)果存儲在useState鉤子的值中。
下面是一個使用該方法獲得一只隨機(jī)貓的例子,使用CatAAS API:
function PromisesPage() { const [catUrl, setCatUrl] = useState(''); const [error, setError] = useState(false); const [state, setState] = useState(''); useEffect(() => { setState('loading'); axios .get('https://cataas.com/cat?json=true') .then((res) => { console.log(res); setState('success'); setCatUrl('https://cataas.com' + res.data.url); }) .catch((err) => { console.error('Error:', err); setState('error'); setError(err); }); }, []); if (state === 'error') return ( <h1> {error.toString()} </h1> ); return ( <div> <div> {state === 'loading' ? ( <h1>Loading...</h1> ) : ( <img src="{catUrl}" /> )} </div> </div> ); }
當(dāng)頁面加載時,useEffect的函數(shù)將被調(diào)用。這將使用axios庫執(zhí)行API調(diào)用,你可以在這里或這里找到更多信息。當(dāng)我們的API調(diào)用正在進(jìn)行時,我們會看到一個加載屏幕;這是一個讓你的用戶了解正在發(fā)生什么的好主意。當(dāng)承諾解決時,我們得到我們所收到的貓,并將其存儲在我們的狀態(tài)中。組件重新渲染,你的貓就被顯示出來了
注意:假設(shè)你的承諾可能會失敗,并為這種可能性做好準(zhǔn)備,這是一個好主意。在這種情況下,如果一個錯誤被拋出,我們會設(shè)置一個不同的狀態(tài)變量,組件會重新渲染,并顯示我們的錯誤信息。
如果你喜歡異步編程的await語法,你可能會發(fā)現(xiàn)上面的代碼有問題。重寫它以使用await,你可以這樣寫。
useEffect(() => { setState('loading'); try { const res = await axios.get('https://cataas.com/cat?json=true'); setCatUrl(res.data.url); setState('success'); } catch (e) { setError(e); } }, []);
但這將引發(fā)一個錯誤,因?yàn)槲覀冊噲D在一個非異步函數(shù)中使用await。我們也不能通過將簽名改為 "async () =>"來使useEffect的函數(shù)成為異步函數(shù),因?yàn)閡seEffect函數(shù)必須是同步的。
useEffect(() => { (async () => { setState('loading'); try { const res = await axios.get('https://cataas.com/cat?json=true'); setCatUrl(res.data.url); setState('success'); } catch (e) { setError(e); } })(); }, []); useEffect(() => { const fetchCat = async () => { setState('loading'); try { const res = await axios.get('https://cataas.com/cat?json=true'); setCatUrl(res.data.url); setState('success'); } catch (e) { setError(e); } }; fetchCat(); }, []);
我們可以用IIFE來解決這個問題,也就是Immediately-Invoked Function Expression。這本質(zhì)上只是定義了一個函數(shù)并立即調(diào)用它,這意味著我們可以在useEffect內(nèi)部的異步函數(shù)中等待我們的承諾。
點(diǎn)擊時
在上面的例子中,我們必須刷新頁面才能得到一只新貓。這有點(diǎn)不方便,所以讓我們重構(gòu)我們的網(wǎng)站,這樣我們就可以通過一個按鈕獲得一只新貓。
function PromisesPage() { const [catUrl, setCatUrl] = useState(''); const [error, setError] = useState(false); const [state, setState] = useState(''); function fetchCat() { setState('loading'); axios .get('https://cataas.com/cat?json=true') .then((res) => { console.log(res); setState('success'); setCatUrl('https://cataas.com' + res.data.url); }) .catch((err) => { console.error('Error:', err); setState('error'); setError(err); }); } useEffect(() => { fetchCat(); }, []); if (state === 'error') return ( <h1> {error.toString()} </h1> ); return ( <div> <div> {state === 'loading' ? ( <h1>Loading...</h1> ) : ( <img src="{catUrl}" /> )} </div> <button> New Cat? </button> </div> ); }
我們把useEffect函數(shù)的內(nèi)容重構(gòu)為自己的獨(dú)立函數(shù),這樣我們就可以隨時觸發(fā)它了
現(xiàn)在,當(dāng)我點(diǎn)擊按鈕時,onClick按鈕會觸發(fā)我們的API請求。當(dāng)我們的承諾得到解決時,該值被存儲在狀態(tài)中,這就觸發(fā)了一次重新渲染。
在這個例子中,我使用了一個API調(diào)用,但你可以用任何承諾來代替它,不管是像useTimeout這樣簡單的東西,還是更復(fù)雜的東西。如果你喜歡這篇文章,如果我?guī)椭鉀Q了你的問題,或者你有任何問題,請在下面的評論中告訴我。
以上就是React中如何處理承諾demo的詳細(xì)內(nèi)容,更多關(guān)于React處理承諾的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
react配置webpack-bundle-analyzer項(xiàng)目優(yōu)化踩坑記錄
這篇文章主要介紹了react配置webpack-bundle-analyzer項(xiàng)目優(yōu)化踩坑記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06React Native仿美團(tuán)下拉菜單的實(shí)例代碼
本篇文章主要介紹了React Native仿美團(tuán)下拉菜單的實(shí)例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08詳解React中多種組件通信方式的實(shí)現(xiàn)
在React中,組件之間的通信是一個非常重要的話題,React提供了幾種方式來實(shí)現(xiàn)跨組件通信,下面小編將詳細(xì)講講其中幾種通信方式,并提供實(shí)際的代碼示例,需要的可以參考下2023-11-11詳解使用React.memo()來優(yōu)化函數(shù)組件的性能
本文講述了開發(fā)React應(yīng)用時如何使用shouldComponentUpdate生命周期函數(shù)以及PureComponent去避免類組件進(jìn)行無用的重渲染,以及如何使用最新的React.memo API去優(yōu)化函數(shù)組件的性能2019-03-03react中如何使用定義數(shù)據(jù)并監(jiān)聽其值
這篇文章主要介紹了react中如何使用定義數(shù)據(jù)并監(jiān)聽其值問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01React Native可定制底板組件Magic Sheet使用示例
這篇文章主要為大家介紹了React Native可定制的底板組件Magic Sheet使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10react中關(guān)于函數(shù)調(diào)用()與bind this的原因及分析
這篇文章主要介紹了react中關(guān)于函數(shù)調(diào)用()與bind this的原因及分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02