背景
我们常常需要请求接口数据,用在页面上展示 比如这样
import axios from "axios";
import { useEffect, useState } from "react";
import { useParams } from "react-router";
import { Loading } from "../components/Loading";
import { Post } from "../components/Post";
import { Comments } from "../components/Comments";
export function PostWithComments() {
const { postId } = useParams();
const [post, setPost] = useState();
const [comments, setComments] = useState();
const [error, setError] = useState(false);
useEffect(() => {
axios
.get(`https://jsonplaceholder.typicode.com/posts/${postId}`)
.then((response) => setPost(response.data))
.catch(() => setError(true));
axios
.get(`https://jsonplaceholder.typicode.com/comments?postId=${postId}`)
.then((response) => setComments(response.data))
.catch(() => setError(true));
}, [postId]);
if (error) {
return <div>Oops, an error occurred</div>;
}
if (!post || !postComments) {
return <Loading />;
}
return (
<section className="post-with-comments">
<Post post={post.data} />
<Comments comments={comments.data} />
</section>
);
}
看起来没啥问题,但如果项目当中有更多的 axios 轻轻,并且 url 前缀都是一样的,之后怎么维护?
axios
.get(`https://jsonplaceholder.typicode.com/posts/${postId}`)
.then((response) => setPost(response.data))
.catch(() => setError(true));
axios
.get(`https://jsonplaceholder.typicode.com/comments?postId=${postId}`)
.then((response) => setComments(response.data))
.catch(() => setError(true));
优化
使用 client.js
import axios from "axios";
export const client = axios.create({
baseURL: "https://jsonplaceholder.typicode.com",
});
使用时 就可直接导入这个 client
import { client } from "../api/client";
...
export function PostWithComments() {
...
useEffect(() => {
client
.get(`/posts/${postId}`)
.then((response) => setPost(response.data))
.catch(() => setError(true));
client
.get(`/comments?postId=${postId}`)
.then((response) => setComments(response.data))
.catch(() => setError(true));
}, [postId]);
...
}
看起来简洁很多,并且如果 url 前缀需要改变,直接去改 client.js 就可以了
不过 还有个问题,这里必须 明确写 .get 或 .post 请求类型,这部分能不能再优化下
再优化
单独函数中隔离 API 调用
import { client } from "./client";
async function getPost(postId: string) {
const response = await client.get(
`/posts/${postId}`
);
return response.data;
}
async function getComments(postId: string) {
const response = await apiClient.get(
`/comments?postId=${postId}`
);
return response.data;
}
export default { getPost, getComments };
这样就可以 直接 使用函数的方式 来调用,而不再需要 单独写
import PostApis from "../api/post";
...
export function PostWithComments() {
const { postId } = useParams();
const [post, setPost] = useState();
const [comments, setComments] = useState();
const [error, setError] = useState(false);
useEffect(() => {
PostApis.getPost(postId)
.then((response) => setPost(response.data))
.catch(() => setError(true));
PostApis.getComments(postId)
.then((response) => setComments(response.data))
.catch(() => setError(true));
}, [postId]);
...
}
这样就更好了