React 中 Promise 的优雅用法,提升应用体验
2023-05-01 00:59:50
React 中优雅使用 Promise 的指南
在现代的 React 应用中,异步操作已成为常态。无论是网络请求、数据库查询还是任何其他长时间运行的任务,我们都必须处理它们。Promise 是 JavaScript 中处理异步操作的强大工具,它使我们能够获取结果或处理错误,而无需阻塞主线程。
使用 React 展示加载态和错误态
React 提供了内置功能,可以轻松地展示 Promise 的加载态和错误态,从而提升用户体验。
Suspense 组件允许我们在等待 Promise 完成时显示加载态。只要将 Promise 作为 Suspense
组件的子组件即可。例如:
import React, { useState, Suspense } from "react";
const MyComponent = () => {
const [isLoading, setIsLoading] = useState(true);
const fetchData = () => {
setIsLoading(true);
return new Promise((resolve) => {
setTimeout(() => {
resolve("Data fetched");
setIsLoading(false);
}, 1000);
});
};
return (
<Suspense fallback={<div>Loading...</div>}>
<div>{fetchData()}</div>
</Suspense>
);
};
export default MyComponent;
ErrorBoundary 组件允许我们在 Promise 发生错误时显示错误态。与 Suspense
组件类似,只需将 Promise 作为 ErrorBoundary
组件的子组件即可。例如:
import React, { useState, ErrorBoundary } from "react";
const MyComponent = () => {
const [isError, setIsError] = useState(false);
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("Error occurred");
}, 1000);
});
};
return (
<ErrorBoundary>
<div>{fetchData()}</div>
</ErrorBoundary>
);
};
export default MyComponent;
React Router 和 Promise
React Router 是一个流行的路由库,它提供了 useFetch()
钩子,可以轻松地将首屏网络请求与 Promise 结合起来。
import React, { useEffect, useState } from "react";
import { useFetch } from "react-router";
const MyComponent = () => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
const response = await useFetch("/api/data");
setData(response.data);
setIsLoading(false);
};
fetchData();
}, []);
return (
<div>
{isLoading ? <div>Loading...</div> : <div>{data}</div>}
</div>
);
};
export default MyComponent;
重试请求
有时,我们可能需要重试失败的请求。我们可以使用 Promise.retry()
方法轻松实现这一点。
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("Error occurred");
}, 1000);
});
};
const retryFetchData = async () => {
try {
await fetchData();
} catch (error) {
// Retry the request
await retryFetchData();
}
};
状态管理
状态管理库,如 Redux,可以帮助我们维护 Promise 的加载态和错误态。
const initialState = {
isLoading: false,
isError: false,
data: null,
};
const reducer = (state, action) => {
switch (action.type) {
case "FETCH_DATA_START":
return {
...state,
isLoading: true,
};
case "FETCH_DATA_SUCCESS":
return {
...state,
isLoading: false,
data: action.payload,
};
case "FETCH_DATA_ERROR":
return {
...state,
isLoading: false,
isError: true,
};
default:
return state;
}
};
const store = createStore(reducer, initialState);
然后,我们可以在组件中使用 useSelector()
和 useDispatch()
钩子来访问和更新状态。
import React, { useSelector, useDispatch } from "react";
const MyComponent = () => {
const isLoading = useSelector((state) => state.isLoading);
const isError = useSelector((state) => state.isError);
const data = useSelector((state) => state.data);
const dispatch = useDispatch();
const fetchData = async () => {
dispatch({ type: "FETCH_DATA_START" });
try {
const response = await fetch("/api/data");
dispatch({ type: "FETCH_DATA_SUCCESS", payload: response.data });
} catch (error) {
dispatch({ type: "FETCH_DATA_ERROR" });
}
};
return (
<div>
{isLoading ? <div>Loading...</div> : <div>{data}</div>}
{isError && <div>Error occurred</div>}
<button onClick={fetchData}>Refresh</button>
</div>
);
};
export default MyComponent;
结论
在 React 应用中使用 Promise 可以显著提升用户体验,帮助我们优雅地处理异步操作。React 提供了内置功能和实用工具来展示加载态和错误态,而状态管理库可以帮助我们维护 Promise 的状态。通过遵循最佳实践,我们可以构建健壮且响应迅速的 React 应用。
常见问题解答
-
如何处理并行 Promise?
使用Promise.all()
或Promise.race()
来处理多个 Promise。 -
Promise 的 reject 和 throw 有什么区别?
reject
是用于明确拒绝 Promise 的方法,而throw
是用于在 Promise 的执行过程中引发错误。 -
如何取消 Promise?
通过实现AbortController
接口来取消 Promise。 -
如何获得 Promise 的当前状态?
使用Promise.resolve()
、Promise.reject()
或Promise.race()
来获取 Promise 的当前状态。 -
如何使用 Promise 进行异步编程?
通过将异步操作封装在 Promise 中并使用await
来使用 Promise 进行异步编程。