react+ts+mobx+router+antd

2023-05-16

安装

npx create-react-app my-app --template typescript
# or
yarn create react-app my-app --template typescript

yarn
# or
npm i
# 添加路由
npm install --save react-router-dom
# 暴露路由
yarn run eject

# 支持less
npm install less-loader less --save

支持less

yarn run eject之后,安装less模块npm install less-loader less --save
在根目录下config\webpack.config.js内找到加入如下代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0aCQusHd-1585184487761)(https://i.loli.net/2020/03/05/CayIKAHfeWrXLtN.png)]

// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;

+ const lessRegex = /\.less$/;
+ const lessModuleRegex = /\.module\.less$/;

在 大约350行左右,找到oneOf的数组,在sass模块下,加入如下 less规则。并将importLoaders: 3中的3改为2

 {
              test: lessRegex,
              exclude: lessModuleRegex,
              use: getStyleLoaders(
                {
                  // importLoaders: 3,
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                },
                'less-loader'
              ),
              sideEffects: true,
            },
            {
              test: lessModuleRegex,
              use: getStyleLoaders(
                {
                  // importLoaders: 3,
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  modules: {
                    getLocalIdent: getCSSModuleLocalIdent,
                  },
                },
                'less-loader'
              ),
            },

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KuhNto5t-1585184487771)(https://i.loli.net/2020/03/05/RSLznh92xbQGsqk.png)]

安装 antd

  • antd design
# 安装antd
npm install antd --save
# 安装 按需加载 
npm install babel-plugin-import --save-dev

package.json添加配置

  "babel": {
    "presets": [
      "react-app"
    ],
+    "plugins": [
+      ["import", {
+        "libraryName": "antd",
+        "libraryDirectory": "es",
+        "style": "css" 
+      }]
+    ]
  }
}

按需加载

npm install babel-plugin-import --save-dev

router 页面布局

安装路由

npm i react-router-dom
npm install --save-dev  @types/react @types/react-dom @types/react-router-dom
  • react-router-dom
    做成后台公共组件的形式,需要把 登录页面 和 错误页面暴露出去;这时候遇到问题,两种解决方案。
  1. 将404、500等报错页面放到公共组件下面。
  2. 每个路由包一层layout,单独放 login 和 404、500等报错页面。

使用withRouter 报错

一个资深大神给的建议:说 mobx 和 react-router-dom 这两个包不兼容的时候,使用any;就可以了。如下:

@(withRouter as any)

antd 4.x 版本icon 变成按需引入

antd 4.x 版本icon 变成按需引入,icon不能一次全部加载进去,下面 是解决方案。

  • icon

安装 mobx


使用Mobx作为app状态管理方案

记得安装 MobX Developer Tools

mobx 开发 谷歌插件

  • https://cn.mobx.js.org/
npm install --save mobx mobx-react
# 安装 装饰器 将 class或者object 转成 ES5
npm install --save-dev @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators

npm install babel-plugin-transform-class-properties -D

npm install --save-dev babel-plugin-transform-decorators-legacy

并在tsconfig.json中加入一行配置来使ts支持装饰器语法:

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

Mobx 用法示例

  1. src下建立stores文件夹。并依次建立detail.tsindex.ts
reatc-example
├── src
│   ├── stores
│   │   │── detail.ts
│   │   └── index.ts
│   └── index.tsx
├── config
│   └── webpack.config.js
└── package.json
  1. detail.ts文件
//detail.ts
import { action, observable } from 'mobx'

interface Cat {
    name: string;
    age?: number | string;
    color?: string;
}
export default class DetailStore {

    @observable name: string = 'Clint'
    @observable arr: Cat[] = []

    constructor(initialState: any = { name: 'detail-store', arr: [{ name: 'Tom', color: 'red' },{ name: 'Jerry',age:'3', color: 'blue' }] }) {
        this.name = initialState.name;
        this.arr = initialState.arr;
    }

    @action
    public setName = (name: string) => {
        this.name = name
    }
    public changeArray = (item: Cat) => {
        this.arr.push(item)
    }
}
  1. index.ts文件,store的初始化
//index.ts
import HomeStore from './home'
import DetailStore from './detail'

export default {
    homeStore: new HomeStore(),
    detailStore: new DetailStore(),
}
  1. 配置Provider 在src/index.tsx
// src/index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'mobx-react'

import Router from './router/router';
// import './index.css';
import stores from './stores/index';
// import * as serviceWorker from './serviceWorker';

ReactDOM.render(
    <Provider {...stores}>
        <Router />
    </Provider>,
    document.getElementById('root'));
  1. 使用store
    注意这里 在react 中,会用到装饰器,而装饰器写法只能在 class 类组件中使用。而 函数式组件 只能 使用嵌套的方式。
    一、 第一种 class 组件中。
// home.tsx
import React, { Component } from 'react';
import { Link } from "react-router-dom";
import { Button } from 'antd';
import { observer, inject } from 'mobx-react'
import homeStore from '../../stores/home'
import './home.less';
type IProps = {
    homeStore: homeStore
    errors?: string
}
@inject('homeStore')
@observer
class Home extends Component<IProps> {
    private clickHandler = (): void => {
        // const { homeStore } = this.props;
        // homeStore.setName("Bob");
        const {setName}=this.props.homeStore
        setName("Bob666")
    }

    render() {
        return (
            <div className="home">
                <h1 className='home-item'>Home</h1>
                <h2>{this.props.homeStore.name}</h2>
                <Link to='/detail'>详情</Link>
                <Link to='/login'>登录</Link>
                <Button onClick={this.clickHandler} type="primary">改名字</Button>
            </div>
        )
    }
};
export default Home;

【注意】如果 在store 里面,声明的 action 函数,不是用的 => 函数,可能出现this指向问题。如下面的例子:

/**
 * 第一种
*/
// store 中
  @action
  public setName(name: string) {
    // 没有使用 箭头函数
    this.name = name
  }
  // 使用
  private clickHandler = (): void => {
        const {setName}=this.props.homeStore
        setName("Bob666")
        // 这时候 this 指向 undefined
        // 所以 报错,可以改写成下面方式,即可解决
        // const { homeStore } = this.props;
        // homeStore.setName("Bob");
  }
/**
 * 第二种
*/
  @action
  public setName = (name: string) => {
    // 箭头函数
    this.name = name
  }
  //使用
    private clickHandler = (): void => {
        const {setName}=this.props.homeStore
        setName("Bob666")
        // 这时候 this 指向 store
        // 成功
  }

二、 第二种 函数 组件中

import React from 'react';
import { Link } from "react-router-dom";
import { observer, inject } from 'mobx-react'
type IProps = {
    [key: string]: any
}
const Detail: React.FC<{}> = inject('detailStore')(observer((props: IProps) => (
    <div className="App">
        <h3>Detail</h3>
        <h6>{props.detailStore.name}</h6>
        <ul>
            {props.detailStore.arr.map((v: any) => <li key={v.name}>{v.name}</li>)}
        </ul>
        <Link to='/home'>首页</Link>
        <Link to='/lll'>空页面</Link>
    </div>
)));

export default Detail;

fetch && axios

  1. 安装 js-cookie
npm i js-cookie @types/js-cookie --save
  1. 使用 fetch
  • Fetch
    utils/request-fetch.ts文件夹下

打包

npm run build

但是 会生成.map文件;上线的时候我们需要去掉这个文件。
config/webpack.config.js内 第33行

// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';

直接将改为

const shouldUseSourceMap = 'false';

即可。
第二种办法,由上面的信息可知,.map文件是由回家变量process.env.GENERATE_SOURCEMAP控制的。所以由于打包的时候执行的脚本文件是scripts/build.js,所在在scripts/build.js内添加如下代码即可。

// 打包禁止生成 .map 文件
process.env.GENERATE_SOURCEMAP = 'false';

报错

  1. yarn or npm
Attempted import error: 'Route' is not exported from 'react-router-dom'.
  • Attempted import error: ‘Route’ is not exported from ‘react-router-dom’
    npm 或者yarn只能使用一种方式。
  1. pages/login/components/LoginForm.tsx中引入store会报错。
  • inject error
  1. Instance created byuseFormis not connect to any Form element. Forget to passformprop?报错
  • https://github.com/ant-design/ant-design/issues/21543
    在这里插入图片描述
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

react+ts+mobx+router+antd 的相关文章

随机推荐

  • 斐波那契数列的递归优化《备忘录递归》

    暴力递归 斐波那契数列的数学形式就是递归 xff0c 直接上代码 xff1a span class token keyword public span span class token keyword static span span cl
  • SaaS多租户数据隔离的三种解决方案

    什么是SaaS xff1f SaaS是Software as a Service的缩写 xff0c 意为软件即服务 SaaS是一种软件部署模式 xff0c 第三方供应商在云基础设施上构建应用程序 xff0c 并以订阅的形式 xff0c 通过
  • 值得收藏的几个postman特色功能帮你事半功倍!

    为什么选择postman xff1f 目前市面上提供了以下几种接口测试工具 xff1a Apifox apifox的官方的定位是 xff1a Apifox 61 Postman 43 Swagger 43 Mock 43 JMeter 有桌
  • 看看大神是怎么在spring中运用设计模式的

    Spring中涉及的设计模式总结 1 简单工厂 非23种设计模式中的一种 实现方式 xff1a BeanFactory Spring中的BeanFactory就是简单工厂模式的体现 xff0c 根据传入一个唯一的标识来获得Bean对象 xf
  • JVM调参,看这一篇就够了

    文章目录 JVM相关参数调试内存相关垃圾回收器相关配置方式命令参考 JVM相关参数调试 通过实战的 方式来进行参数调试 xff0c 观察结果才能真正理解含义 xff0c 下面将通过一段代码 xff0c 来一个一个参数的进行测试 代码示例 后
  • JVM的内存结构

    JVM入门 jvm基础 什么是jvm 定义 xff1a Java Virtual Machine java 程序的运行环境 xff08 java 二进制字节码的运行环境 xff09 好处 xff1a 一次编写 xff0c 到处运行的基石自动
  • leetcode-3.无重复字符的最长子串

    给定一个字符串 s xff0c 请你找出其中不含有重复字符的 最长子串 的长度 示例 1 输入 s 61 abcabcbb 输出 3 解释 因为无重复字符的最长子串是 abc xff0c 所以其长度为 3 示例 2 输入 s 61 bbbb
  • 如何重启 Windows 10 子系统(WSL) ubuntu

    如何重启 Windows 10 子系统 xff08 WSL ubuntu WSL 子系统是基于 LxssManager 服务运行的 只需要将 LxssManager 重启即可 可以做成一个 bat 文件 net stop LxssManag
  • Mysql引擎innodb行锁的三种算法

    Mysql中的锁 基于锁的属性分类 xff1a 共享锁 排他锁 基于锁的状态分类 xff1a 意向共享锁 意向排它锁 根据锁的粒度分类 xff1a 全局锁 页锁 表级锁 行锁 xff08 记录锁 间隙锁 和临键锁 xff09 xff0c 实
  • Mysql引擎innodb的脏读,不可重复读,幻读问题

    脏读 概念 脏数据是指事务对缓冲池中行记录的修改 xff0c 并且还没有被提交 xff0c 就可能造成另一个事务读取到了另一个事务未提交的数据 xff0c 违反了数据库的隔离性 脏数据的读取 示例 xff1a 上面示例的隔离级别换成了REA
  • 自从用了checkstyle,代码一天比一天规范

    文章目录 概述特征配置checkstyle文件概述checkstyle文件的模块编写checkstyle文件引入checkstyle插件测试checkstyle 参考文档 概述 Checkstyle 是一种开发工具 xff0c 可帮助程序员
  • 数据结构系列之跳表

    什么是跳表 跳表是一种数据结构 它允许快速查询一个有序连续元素的数据链表 跳跃列表的平均查找和插入时间复杂度都是O log n xff0c 优于普通队列的O n 引题 线性表这种数据有两种具体实现 数组和链表 具体的内容之前的文章里也有说过
  • 分布式理论之CAP

    文章目录 引言1 CAP 的由来2 CAP 到底是什么2 1 C xff1a 数据一致性2 2 A xff1a 可用性2 3 P xff1a 分区容错性 3 CAP 怎么选择4 对 CAP 的常见误解6 CAP 的不足7 引申出来的 BAS
  • 优雅的处理sping项目全局异常

    全局异常处理 为了达到系统的各个模块中都能够共用同一个异常处理逻辑 xff0c 避免代码重复和错误 在Spring框架中 xff0c 可以通过全局异常处理来捕获应用程序中抛出的异常 xff0c 并根据需要进行处理 64 Controller
  • MapReduce优缺点

    优点 1 xff0e MapReduce 易于编程 它简单的实现一些接口 xff0c 就可以完成一个分布式程序 xff0c 这个分布式程序可以分布到大量廉价的PC机器上运行 也就是说你写一个分布式程序 xff0c 跟写一个简单的串行程序是一
  • ubuntu下nginx配置不生效,页面一直是默认页面welcome to nginx

    ubuntu下nginx的配置文件所在目录 xff1a etc nginx 我的问题是 监听80端口 xff1b 如果是其他的端口就是OK的 xff0c 只要一切换到80端口 xff0c 就自动是默认页面welcome to nginx 我
  • 埋点统计

    body 监听点击时间 但是要计算点击位置 开源的系统countly页面热区统计百度埋点诸葛io xff0c 易观方舟第三方https zhuanlan zhihu com p 65834362https github com 534591
  • 从零搭建vue 项目(一)

    从零搭建vue 项目 xff08 一 xff09 我的博客 代码地址 代码地址 首先4个官方文档 VueVue CLIVue RouterVuex 创建vuedemo的项目 npx 64 vue cli create vuedemo spa
  • ubuntu 18.04 桌面安装 tasksel aptitude failed (100) 问题修复

    ubuntu 18 04 桌面无法启动 xff0c 可能是安装远程桌面时搞坏了图形桌面的配置 因为实在百度不到具体出错的文件和相关配置 只能删除了桌面系统 然后问题来了 xff0c sudo apt install ubuntu desk
  • react+ts+mobx+router+antd

    安装 npx create react app my app template typescript span class token comment or span yarn create react app my app templat