大概是在上一个月,偶尔瞅到小野老师封装的GET组件,今天跟着做了一下,发现很多坑,卑微的我只能在博客里吐槽几句。
视频地址:【全网首发:已完结】React『封装HTTP工具组件』【前端学习能力提升】_哔哩哔哩_bilibili
代码实现
App.tsx中使用Get组件
// src/App.tsx
import React, { useEffect, useState } from "react";
import "./App.css";
import Get from "./component/Get.jsx";
function App() {
return (
<Get
url="http://localhost:8080/api/zhihu"
loading={() => {
return (
<div className="container">
<h1 className="text">Loading...</h1>
</div>
);
}}
error={(err) => {
<div className="container">
<h1 className="error">{err.message}</h1>
</div>;
}}
>
{(data) => {
return (
<div className="container">
<h1 className="emoji">{data.greeting.emoji}</h1>
<h1 className="text">{data.greeting.text}</h1>
</div>
);
}}
</Get>
);
}
export default App;
Get组件细节
// src/component/Get.tsx
import React, { useEffect, useState } from "react";
import axios from "axios";
export default function GET(props) {
const { url, params = {}, loading = "", error = "", children } = props;
// 拿到组件参数,默认返回loading
const [component, setComponent] = useState(loading());
useEffect(() => {
(async () => {
try {
// 请求结束后将result.data回调
const result = await axios.get(url, { params });
setComponent(children(result.data));
} catch (err) {
// reject回调
setComponent(error(err));
}
})();
}, []);
return component;
}
App.css
// src/App.css
.container .emoji {
text-align: center;
}
.container .text {
background-image: -webkit-gradient(
linear,
left 0,
right 0,
from(rgb(4, 94, 170)),
to(rgb(1, 152, 216))
);
-webkit-background-clip: text; /*必需加前缀 -webkit- 才支持这个text值 */
-webkit-text-fill-color: transparent; /*text-fill-color会覆盖color所定义的字体颜色: */
}
.container .error {
background-image: -webkit-gradient(
linear,
left 0,
right 0,
from(rgb(233, 94, 170)),
to(rgb(190, 100, 216))
);
-webkit-background-clip: text; /*必需加前缀 -webkit- 才支持这个text值 */
-webkit-text-fill-color: transparent; /*text-fill-color会覆盖color所定义的字体颜色: */
}
后端express代码
// server/src/api.js
const express = require("express");
const router = express.Router();
const axios = require("axios");
const corsOptions = {
origin: "http://localhost:3000", //只有localhost:3000可以访问
optionsSuccessStatus: 200,
};
const cors = require("cors");
router.get("/zhihu", cors(corsOptions), async (req, res) => {
const sentence = await axios.get(
"https://www.zhihu.com/api/v4/clubs/1174735957173088256/checkin",
{
headers: {
cookie: `*********************`,
},
}
);
res.send(sentence.data);
res.end();
});
module.exports = router;
效果
总结
小野老师用classComponent实现的,我换种写法,用functionalComponent
以前知乎这个接口不需要cookie来着,今天不加cookie就404了。
刚开始没有出现跨域问题,莫名其妙,我还纳闷了。
对接好知乎的接口以后就开始提示跨域了,记得Vue是在Vue.config.js设置代理服务器来着,这次react不知道在哪搞,网上说装一个http-proxy-middleware模块,看着文章也没讲明白,底下评论说要先npm run eject,但我这是用vite创建的项目呀,那个是create-react-app上的。
最终是在node服务端使用cors模块解决的,神奇。
代码已经放在我的笔记仓库里了。
MyCodebak/Web/react/http-component at master · sunzehui/MyCodebak (github.com)
success::note 第二天回来补充:已经解决了,在vite中配置代理服务器解决跨域问题 - 孙泽辉 (foggy.shop)