react-router

主要记录 v6

  • react-router:包含了 react-native 中需要的一些组件
  • react-router-dom:web 用这个即可

BrowserRouter

通常用于最外层,其内部实现是用了 history 这个库和 React Context 来实现的,当进行前进后退时,history 这个库会记住用户的历史记录,这样需要跳转时可以直接操作

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById('app')
);

Route

Route 用来定义一个访问路径与 React 组件之间的关系

比如,希望访问 https://your_site.com/about 的时候加载 <About /> 这个页面,那么如下使用 Route

<Route path="/about" element={<About />} />

Routes

Routes 是用来包住路由访问路径 Route 的,它决定用户在浏览器中输入的路径到对应加载什么 React 组件,因此绝大多数情况下,Routes 的唯一作用是用来包住一系列的 Route

function App() {
    return (
        <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/about" element={<About />} />
        </Routes>
    );
}

自定义 create-react-app 配置

使用 @craco/craco

安装之后更改打包命令为

// package.json
{
    ...
    "scripts": {
        "start": "craco start",
        "build": "craco build",
        "test": "craco test",
        "eject": "craco eject"
    }
    ...
}

然后在根目录创建 craco.config.js

// craco.config.js

moule.exports = {
    ...
}

配置 别名

eslint-plugin-import 在初始化 eslint 时已自动安装,因此只需另外安装 eslint-import-resolver-typescript 即可

然后更改两个文件配置

// tsconfig.json
{
    ...
    "baseUrl": ".",
    "paths:" {
        "@/*": ["src/*"]
    }
    ...
}
// .eslintrc.js
module.exports = {
    ...
    settings: {
        'import/resolve': {
            typescript: {
                project: path.join(__dirname, './tsconfig.json'),
                alwaysTryTypes: true
            },
            alias: {
                map: [['@', './src']] // 该条配置好像不需要,上面读取了 ts 的配置
            }
        }
    }
    ...
}

路由拦截

定义拦截组件

import React from 'react';
import { Navigate } from 'react-router-dom';

function RouteInterceptor({ props, children }: { props: any; children: any }) {
    const isLogin = localStorage.getItem('isLogin');
    const needLogin = props?.meta?.needLogin;

    if (needLogin && !isLogin) {
        return <Navigate to="/login" replace />;
    }
    return children;
}

export default RouteInterceptor;

此处 eslint 会报错,为了避免多次配置,因此添加规则

rulse: {
    'react/prop-types': 0,
}

使用

<Route
    path={item.path}
    key={item.path}
    element={
        <RouteInterceptor props={item}>
            <item.component />
        </RouteInterceptor>
    }
/>

axios

动态引入文件

// api/index.js
let temp = {};
const files = require.context('./', true, /\.ts$/);
files.keys().forEach((filename: string) => {
    if (filename === './index.ts' || filename.indexOf('/index.ts') < 0) {
        return;
    }
    temp = { ...temp, ...files(filename).default };
});

const api = { ...temp };
export default api;

此时会提示错误:类型 NodeRequire 上不存在属性 context

需进行以下操作

  • 安装 @types/webpack-env

  • tsconfig.json 新增配置

    {
        "compilerOptions": {
            "types": ["webpack-env"]
        }
    }
    
Last Updated:
Contributors: zhangfei