抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

大概是在上一个月,偶尔瞅到小野老师封装的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)

评论