處理非同步操作是 React 應用程式中的常見要求,尤其是在使用 API、資料庫或外部服務時。由於 JavaScript 操作(例如從 API 獲取資料或執行計算)通常是非同步的,因此 React 提供了工具和技術來優雅地處理它們。
在本指南中,我們將使用 async/await、Promises 和其他 React 特定工具來探索在 React 中處理非同步呼叫的不同方法。
React 的 useEffect 鉤子非常適合執行副作用,例如在元件安裝時取得資料。鉤子本身不能直接返回承諾,因此我們在效果中使用非同步函數。
以下是如何使用 useEffect 掛鉤處理非同步呼叫以取得資料。
import React, { useState, useEffect } from 'react'; const API_URL = 'https://jsonplaceholder.typicode.com/posts'; // Example API const AsyncFetchExample = () => { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // Using async/await inside useEffect useEffect(() => { const fetchData = async () => { try { const response = await fetch(API_URL); if (!response.ok) { throw new Error('Failed to fetch data'); } const data = await response.json(); setPosts(data); } catch (error) { setError(error.message); } finally { setLoading(false); } }; fetchData(); // Call the async function }, []); // Empty dependency array means this effect runs once when the component mounts if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>; return ( <div> <h1>Posts</h1> <ul> {posts.map((post) => ( <li key={post.id}> <h2>{post.title}</h2> <p>{post.body}</p> </li> ))} </ul> </div> ); }; export default AsyncFetchExample;
另一種常見方法是直接將 Promises 與 then() 和 catch() 結合使用。這種方法不如 async/await 優雅,但在 JavaScript 中仍然廣泛用於處理非同步操作。
這是一個使用 Promise 和 then() 進行非同步呼叫的範例:
import React, { useState, useEffect } from 'react'; const API_URL = 'https://jsonplaceholder.typicode.com/posts'; const AsyncFetchWithPromise = () => { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetch(API_URL) .then((response) => { if (!response.ok) { throw new Error('Failed to fetch data'); } return response.json(); }) .then((data) => { setPosts(data); setLoading(false); }) .catch((error) => { setError(error.message); setLoading(false); }); }, []); if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>; return ( <div> <h1>Posts</h1> <ul> {posts.map((post) => ( <li key={post.id}> <h2>{post.title}</h2> <p>{post.body}</p> </li> ))} </ul> </div> ); }; export default AsyncFetchWithPromise;
當您有更複雜的狀態轉換或需要在非同步過程中處理多個操作(如載入、成功、錯誤)時,useReducer 是管理狀態變更的絕佳工具。
import React, { useState, useEffect } from 'react'; const API_URL = 'https://jsonplaceholder.typicode.com/posts'; // Example API const AsyncFetchExample = () => { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // Using async/await inside useEffect useEffect(() => { const fetchData = async () => { try { const response = await fetch(API_URL); if (!response.ok) { throw new Error('Failed to fetch data'); } const data = await response.json(); setPosts(data); } catch (error) { setError(error.message); } finally { setLoading(false); } }; fetchData(); // Call the async function }, []); // Empty dependency array means this effect runs once when the component mounts if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>; return ( <div> <h1>Posts</h1> <ul> {posts.map((post) => ( <li key={post.id}> <h2>{post.title}</h2> <p>{post.body}</p> </li> ))} </ul> </div> ); }; export default AsyncFetchExample;
在某些情況下,您可能希望跨多個元件重複使用非同步邏輯。建立自訂鉤子是封裝邏輯並使程式碼更可重複使用的絕佳方法。
import React, { useState, useEffect } from 'react'; const API_URL = 'https://jsonplaceholder.typicode.com/posts'; const AsyncFetchWithPromise = () => { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetch(API_URL) .then((response) => { if (!response.ok) { throw new Error('Failed to fetch data'); } return response.json(); }) .then((data) => { setPosts(data); setLoading(false); }) .catch((error) => { setError(error.message); setLoading(false); }); }, []); if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>; return ( <div> <h1>Posts</h1> <ul> {posts.map((post) => ( <li key={post.id}> <h2>{post.title}</h2> <p>{post.body}</p> </li> ))} </ul> </div> ); }; export default AsyncFetchWithPromise;
在 React 中處理非同步操作對於建立現代 Web 應用程式至關重要。透過使用 useEffect、useReducer 和自訂鉤子等鉤子,您可以輕鬆管理非同步為、處理錯誤並確保流暢的使用者體驗。無論您是獲取資料、處理錯誤還是執行複雜的非同步邏輯,React 都為您提供了強大的工具來有效管理這些任務。
以上是使用 useEffect、Promises 和自訂 Hooks 處理 React 中的非同步操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!