在任何 Web 应用程序中,管理加载和错误状态至关重要。显示加载状态可以让用户随时了解情况,但从历史上看,手动实施这种管理可能很乏味。
React Query 极大地简化了加载状态和全局状态的处理。事实上,React Query 避免了冗余请求,从而优化了应用程序的性能。
让我们看一个在应用程序中实现加载状态的代码示例。
定义一个钩子来获取用户列表:
export const useUsers = () => { const { data, isLoading } = useQuery<User[]>({ queryKey: ["users"], queryFn: async () => { const response = await fetch("https://jsonplaceholder.typicode.com/users"); await new Promise((resolve) => setTimeout(resolve, 2000)); return response.json(); }, }); return { users: data?.slice(0, 4) || [], isLoading, }; };
在这里,我们使用 useQuery 获取四个用户。我们添加 2 秒的延迟来说明加载状态。然后我们返回数据和加载状态的布尔值。
在组件方面,我们创建一个名为Example的组件:
const Example = (): JSX.Element => { const { users, isLoading } = useUsers(); if (isLoading) { return <div>Loading...</div>; } return ( <div className="container"> <div className="user-action"> <h1>Users</h1> <div> <button>Add users</button> </div> </div> <UsersList users={users} /> </div> ); };
在此组件中,我们使用钩子来获取用户列表。在渲染视图之前,我们执行带有加载消息的“早期返回”,然后显示标题、按钮和用户。
但是,每个网络调用都需要显式管理加载状态。如果代码未分解,视图的某些元素可能正在等待显示,例如标题和操作。
这是避免遮挡视图的替代方法:
import "./App.css"; import UsersList from "./UsersList"; import { useUsers } from "./useUsers"; const Example = (): JSX.Element => { const { users, isLoading } = useUsers(); return ( <div className="container"> <div className="user-action"> <h1>Users</h1> <div> <button>Add users</button> </div> </div> {isLoading ? <div>Loading...</div> : <UsersList users={users} />} </div> ); };
在这里,我们使用条件渲染而不是“提前返回”。该解决方案可读性较差,并且在复杂组件中更难维护。
最巧妙的解决方案是创建一个组件来渲染我们的加载消息或基于变量的主组件。
type Props = PropsWithChildren<{ isLoading: boolean; }>; const LoadingWrapper = ({ children, isLoading }: Props): JSX.Element => { if (isLoading) { return <div>Loading...</div>; } return <>{children}</>; };
在我们的组件中的使用
const Example = (): JSX.Element => { const { users, isLoading } = useUsers(); return ( <div className="container"> ... <LoadingWrapper isLoading={isLoading}> <UsersList users={users} /> </LoadingWrapper> </div> ); };
这种分解集中了条件渲染逻辑并统一了加载消息的使用,提供了更清晰、更易于维护的代码。
但是现在,如果我告诉你,我们刚刚创建的这个组件已经内置到 React 中了。更好的是,它很神奇!不再需要手动管理 isLoading 状态!
有了 React 的 Suspense(React 版本 >= 16.6),一切都变得更简单、更干净。 Suspense 允许您显式向 React 声明组件正在等待异步数据,React 会为我们管理一切。
让我们使用useSuspenseQuery来自动管理加载状态。操作方法如下:
挂钩以获取用户
export const useUsersSuspense = () => { const { data } = useSuspenseQuery<User[]>( ... ); return { users: data?.slice(0, 4) || [], // Without the isLoading }; };
现在,让我们更新示例组件以使用 Suspense:
const UsersComponent = (): JSX.Element => { const { users } = useUsersSuspense(); return <UsersList users={users} />; }; const Example = (): JSX.Element => { return ( <div className="container"> <div className="user-action"> <h1>Users</h1> <div> <button>Add users</button> </div> </div> <Suspense fallback={<div>Loading...</div>}> <UsersComponent /> </Suspense> </div> ); };
通过 Suspense,我们将加载状态的管理集中在一个地方,使代码更具可读性和可维护性。只要数据不可用,Suspense 回退就会自动显示,无需手动管理 isLoading 状态。
此外,Suspense 鼓励开发团队分解他们的代码。通过使用标准化的加载组件和异步状态处理程序,开发人员可以创建可重用且一致的模块,从而长期提高代码质量和可维护性。
使用 Suspense 和 useSuspenseQuery 彻底改变了 React 应用程序中加载状态的管理。这种方法不仅简化了代码,还通过确保平滑一致的渲染来增强用户体验。从 useQuery 过渡到 useSuspenseQuery 是更清洁、更高效的应用程序的自然演变。
此外,集成 Suspense 鼓励开发团队分解他们的代码。总而言之,采用 Suspense 和 useSuspenseQuery 不仅仅是技术上的改进,也是迈向更健康、更有效的开发实践的一步。
我的时事通讯:D
以上是停止使用 React-Query 中的 useQuery !的详细内容。更多信息请关注PHP中文网其他相关文章!