React 中获取数据的神奇方法
如果你用过 React,很可能需要查询 API。网站的数据获取至关重要。要想打造真正令人愉悦的用户体验,数据获取必须做到万无一失。这至关重要。
让我快速带你了解一下 React 应用中传统的查询方法。其中大部分内容可能对你来说很简单,但我们必须了解这些,才能真正体会到react-query 的优势所在。(相信我,它简直太神奇了😉)
我们将使用JSON Placeholder API作为数据源。我们主要会执行两种类型的查询:获取所有帖子列表和获取单个帖子。让我们编写一个钩子来获取所有帖子列表。
const baseUrl = 'https://jsonplaceholder.typicode.com';
const usePosts = () => {
const [data, setData] = useState();
useEffect(() => {
const fetchData = async () => {
const res = await fetch(`${baseUrl}/posts`);
const posts = await res.json();
setData(posts);
};
fetchData();
}, []);
return { data };
};
这看起来应该很眼熟。你会注意到我们还没有处理错误或加载状态。这是不好的做法。我们现在就来处理。
const usePosts = () => {
const [data, setData] = useState();
const [isLoading, setLoading] = useState(true);
const [error, setError] = useState();
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const res = await fetch(`${baseUrl}/posts`);
const posts = await res.json();
setData(posts);
setLoading(false);
} catch (error) {
console.log(error);
setError(error);
setData([]);
setLoading(false);
}
};
fetchData();
}, []);
return { data, isLoading, error };
};
哇……这可真够糟糕的。😒 我们为了让钩子函数支持两个简单的状态,不得不添加大量代码。而且这个查询……基本上每次组件重新渲染都会运行?这远非理想状态。你应该得到更好的体验。
后台更新呢?数据过期呢?分页呢?以编程方式重新运行查询呢?
祝你一切顺利。🤷♂️
这时 react-query 就能派上用场了。如果你想跟着教程一步步操作,可以使用这个仓库作为模板。
现在让我们使用 react-query 重构我们的usePostshook。如果你之前没有使用过 react-query,你将会感到惊喜。
// hooks/hooks.js
const usePosts = () => {
const fetchData = async () => {
return fetch(`${baseUrl}/posts`).then((r) => r.json());
};
return useQuery('posts', fetchData);
};
对,就是这样。我早就跟你说了。😎
同样的方法也适用于usePost钩子。
const usePost = (id) => {
const fetchData = async () => {
return fetch(`${baseUrl}/posts/${id}`).then((r) => r.json());
};
return useQuery(['post', id], fetchData);
};
这段代码就能处理我们用传统方法处理的所有事情——而这仅仅是冰山一角。让我们深入探讨一下。
点击下方截图中显示的图标,打开 react-query 开发者工具。保持其打开状态。 现在在 Web 应用中随意点击,并留意开发者工具。你会看到查询在执行时被记录下来。这非常直观。
我之前提到过,react-query 的功能远不止管理加载、错误等状态。让我来详细介绍其中一项功能——查询失效。简单来说,查询失效就是告诉 react-query 认为某个查询“过期”了,并重新运行该查询。我们来试试看。
我们将在文章列表顶部添加一个重新获取文章列表的按钮。点击此按钮,我们的应用就会重新获取文章列表。由于我们使用了 react-query,所以这对我们来说简直易如反掌。😁
// pages/index.js
import { useQueryClient } from 'react-query';
export default function Home() {
const queryClient = useQueryClient();
const reFetchPosts = () => {
queryClient.invalidateQueries('posts');
};
return (
<Container>
<Button onClick={reFetchPosts}>Re-fetch</Button>
{data.map((post) => {
//...
})}
</Container>
);
}
这就是我们需要添加的全部内容。现在,点击我们新添加的重新获取按钮,并留意 react-query 的开发者工具。你会发现它按预期重新运行了查询。你也可以通过浏览器开发者工具中的“网络”选项卡来验证这一点。
总之,我们把原本27行代码精简到了仅仅7行,却获得了更多可用的功能。我觉得这很划算。🤝
太惊艳了!我保证它真的非常神奇。😊
如果你喜欢这篇文章,请关注我的博客和推特。我主要在推特上吐槽软件,以及炫耀我的小成就。⚡
欢迎在下方留言,发起讨论或提出问题。我会很乐意解答。🤗
参考:
React Query 详解(Tanner Linsley 主讲)—— 跟 Jason 一起学习
React Query - 数据获取钩子 — Leigh Halliday
封面照片由西蒙·伯格拍摄
文章来源:https://dev.to/dhaiwat10/a-magical-way-to-fetch-data-in-react-52m6