React项目全球新闻发布管理系统 - 新版问题解决方式整理及部署网站至 Netlify

整理了一下新版的变化以及遇到的坑的解决办法,最后也会分享将网站及接口部署的方式。

千锋前端-React全家桶_React项目全球新闻发布管理系统
https://www.bilibili.com/video/BV1fw411d7R5

P4

反向代理 setupProxy.js 改为:

// setupProxy.js
const {
    createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
   
  app.use(
    '/api',
    createProxyMiddleware({
   
      target: 'https://i.maoyan.com',
      changeOrigin: true,
    })
  );
};

App.js 中 axios 请求地址改为:

// App.js
useEffect(() => {
   
    axios.get("/api/mmdb/movie/v3/list/hot.json?ct=%E7%B9%81%E6%98%8C%E5%8C%BA&ci=774&channelId=4")
      .then((res) => console.log(res.data));
  }, []);

因为我没有看到视频中用的 m.maoyan.com/ajax 那个地址,所以我自己抓了一个,反正是练习用的就不必那么讲究了,测试一下 middleware 能不能使就行。

P5

15 分处

  • HashRouter 里面包 Switch 会出错,请改为包 Routes (Routes 和 Switch 的功用是一样的,都能做到精准匹配)
  • Route 的 component 属性改为 element,并且 element 中请使用 <> 包裹组件名称
// IndexRouter.js
import React from "react";
import {
    HashRouter, Routes, Route } from "react-router-dom";
import Login from "../views/login/Login";
import NewsSandBox from "../views/newssandbox/NewsSandBox";

export default function IndexRouter () {
   
  return (
    <HashRouter>
      <Routes>
        <Route path="/login" element={
   <Login/>} />
        <Route path="/" element={
   <NewsSandBox/>} />
      </Routes>
    </HashRouter>
  );
};

20 分处重定向部分

For react-router-dom v6, simply replace Redirect with Navigate

所以我们需要将 Redirect 改为 Navigate,并且一样使用的是 element 而不是 render

<Route path="/*" element={
   localStorage.getItem("token") ?  <NewsSandBox/> : <Navigate to="/login"/>} />

P6

14 分处,一样将所有 Switch 改为 Routes, component 改为 element,Redirect 改为 Navigate

//NewsSandBox.js
<Routes>
  <Route path="home" element={
   <Home />} />
  <Route path="user-manage/list" element={
   <UserList />} />
  <Route path="right-manage/role/list" element={
   <RoleList />} />
  <Route path="right-manage/right/list" element={
   <RightList />} />
  <Route path="/" element={
   <Navigate replace from="/" to="home"/>} />
  <Route path="/*" element={
   <NoPermission/>} />
</Routes>

并且要记住的是 Navigate 只能包裹在 Route 中,Routes 中只能有 Route 或者 Fragment

P11

使用 withRouter 会报错:

‘withRouter’ is not exported from ‘react-router-dom’.

因为 V6 之后没有 withRouter 了,所以直接改用 useNavigate 会更方便,完整的 Code 我直接放出来吧:

import React from "react";
import {
    Layout, Menu } from "antd";
import {
    UserOutlined, HomeOutlined, CrownOutlined } from "@ant-design/icons";
import SubMenu from "antd/lib/menu/SubMenu";
import {
    useNavigate } from "react-router";

const {
    Sider } = Layout;

const menuList = [
  {
   
    key: "/home",
    title: "首页",
    icon: <HomeOutlined />,
  },
  {
   
    key: "/user-manage",
    title: "用户管理",
    icon: <UserOutlined />,
    children: [
      {
   
        key: "/user-manage/list",
        title: "用户列表",
        icon: <UserOutlined />,
      },
    ],
  },
  {
   
    key: "/right-manage",
    title: "权限管理",
    icon: <CrownOutlined />,
    children: [
      {
   
        key: "/right-manage/role/list",
        title: "角色列表",
        icon: <CrownOutlined />,
      },
      {
   
        key: "/right-manage/right/list",
        title: "权限列表",
        icon: <CrownOutlined />,
      },
    ],
  },
];

export default function SideMenu({
     collapsed }) {
   
  let navigate = useNavigate();
  // Menu
  const renderMenu = (menuList) => {
   
    return menuList.map((item) => {
   
      if (item.children) {
   
        return (
          <SubMenu key={
   item.key} icon={
   item.icon} title={
   item.title}>
            {
   renderMenu(item.children)}
          </SubMenu>
        );
      }
      return (
        <Menu.Item
          key={
   item.key}
          icon={
   item.icon}
          onClick={
   () => navigate(item.key)}
        >
          {
   item.title}
        </Menu.Item>
      );
    });
  };

  return (
    <Sider trigger={
   null} collapsible collapsed={
   collapsed}>
      <div className="logo" />
      <Menu theme="dark" mode="inline" defaultSelectedKeys={
   ["1"]}>
        {
   renderMenu(menuList)}
      </Menu>
    </Sider>
  );
}

P15

props.location.pathname 可以用 useLocation 钩子取代,与 props.location 是一样的用法:

import {
    useNavigate, useLocation } from "react-router";
// ...
let location = useLocation();
const selectKeys = [location.pathname]; // ex: ['/home']
const openKeys = ["/" + location.pathname.split("/")[1]];
// ...
<Menu theme="dark" mode="inline" selectedKeys={
   selectKeys} defaultOpenKeys={
   openKeys}>
  {
   renderMenu(menu)}
</Menu>

P17

直接写 res.data[0].children = "" 的话一旦 array 内容顺序有所变更就会错误,因此建议透过遍历的方式寻找 children 长度为 0 的元素,将它改为空字串。

useEffect(() => {
   
  axios.get("http://localhost:8000/rights?_embed=children")
  .then((res) => {
   
    res.data.forEach((item) => item.children?.length === 0 ? item.children = "" : item.children);
    setDataSource(res.data);
  })
}, []);

P18

个人认为删除后页面要会 auto refresh,所以我改写了一下,这样只要删除权限时就会修改 refresh 的状态,而 refresh 状态一变更就会重新 call API 获取数据。

// RightList.js
const [dataSource, setDataSource] = useState([]);
const [refresh, setRefresh] = useState(false);

useEffect(() => {
   
  axios.get("http://localhost:8000/rights?_embed=children").then((res) => {
   
  • 32
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值