React实战系列-布局与组件【1】

民之从事,常于几成而败之。慎终如始,则无败事。— 《道德经》第64章

原本打算做的网易音乐后台要搁浅了
首先我觉得这个并不适合我

原因有以下几个方面:

  1. 跳跃过大
  2. 自定义模块过多

虽说跟着一遍做一遍摸索,可以完成,但我觉得太浪费时间,终究没有个流程。

我的目标是:

  1. 掌握数据流管理方案–redux及其配套设施;
  2. 熟悉react、react-router-dom、react-router的应用场景以及注意事项;
  3. 熟练使用antd的组件;
  4. —-完成前端应用—–
  5. Eggjs + Mysql 提供数据服务
  6. 进一步完善前后端

开篇

以上的目标打算抽时间逐步完成,这个系列博客,尽量写明白写清楚,也算是职业生涯中的值得回忆的一个成就。
因为是一边学习一边记录,所以采取由浅入深的开发流程。

说明

为了完成目标,确定的目标项目是开源的—-react-admin;打算在此基础上进行改写并完成一个相对完善的后端项目。

这篇文章说明的文字较多。

原生化

  1. 尽可能的只用原生组件,目光始终在完成需求上;
  2. 尽可能用不同的方式完成同样的需求;
  3. 尽可能好的组织代码方式

技术栈

大致分为以下几类,还会涉及其余的相关模块等,后续会在相关位置添加链接或单独写文章整理。

  1. 语言:
    1. TS
    2. Less
  2. React:
    1. React
    2. react-router
    3. react-router-dom
  3. 状态管理:
    1. Redux
    2. React-Redux
    3. Redux-Saga
    4. Immer
  4. UI:
    1. Antd
    2. echartsjs
    3. echarts-for-react

疑问解答

采用官方脚手架–create-react-app

为何不用dvajs?

综合性很强,但我认为应该先难后易

为何不用umi?

综合性更强,仍旧认为应该先难后易

学习node,我觉得先了解express,再写koa,最后采用egg 是个不错的选择。

建议不要eject!

初心是学习react全家桶,不是webpack【后期有空再学】, 至于less相关配置,可以换个做法

开动

由于打算写这个系列的文章的时候,基本的UI框架已经搭建好,现在就把文件目录罗列出来,并加以说明,针对这个过程中遇到的问题,会在之后一一罗列,代码中几乎都会有注释。

.
├── README\ 2.md # 说明文件
├── README.md # 说明文件
├── config-overrides.js # less 相关配置
├── package-lock.json
├── package.json
├── public # 资源文件
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src # 代码区
│ ├── App.less # 布局文件
│ ├── App.test.tsx # 测试文件
│ ├── App.tsx # 入口布局
│ ├── Page.tsx # 入口文件
│ ├── components #组件
│ │ ├── HeaderCustom.tsx # 头部组件
│ │ ├── SiderCustom.tsx # 侧边栏
│ │ ├── SiderMenu.tsx # 侧边栏菜单
│ │ ├── forms # 文件夹--表单
│ │ ├── index.tsx # 组件统一导出文件
│ │ ├── pages # 单页面,如404
│ │ └── widget # 小组件,如copyright
│ ├── containers # 容器组件
│ │ └── XXX # 后期会增加
│ ├── images # 图片
│ ├── index.css
│ ├── index.tsx # 入口配置文件
│ ├── react-app-env.d.ts # .d.ts文件
│ ├── redux # redux 相关
│ │ ├── configureStore.ts # 统一配置redux
│ │ └── modules # redux modules 文件夹
│ ├── routes # 路由配置文件夹
│ │ ├── config.ts # 路由的配置文件
│ │ └── index.tsx # 遍历配置文件,并初始化路由
│ ├── serviceWorker.ts
│ ├── setupTests.ts
│ ├── style # 样式文件夹
│ │ ├── antd
│ │ ├── imgs
│ │ └── index.less
│ ├── test.js
│ └── utils # 小功能
│ ├── antdValidate.ts
│ └── index.ts
└── tsconfig.json

采用 Create React App TS.

步骤一 初始化

# --- 初始化
$ npx create-react-app react-project --typescript
$ # 或者
$ yarn create react-app react-project --typescript

# --- TS相关依赖
$ npm install --save typescript @types/node @types/react @types/react-dom @types/jest
$ # 或者
$ yarn add typescript @types/node @types/react @types/react-dom @types/jest

# --- 启动
$ cd react-project
$ npm start

以上构建好&启动了项目。

步骤二 下载相关依赖

其实应该用到啥配置啥,这样更能明白,但是现在只能罗列下,建文件夹、下载、、、都太简单了.

换个思路,把目前需要的包罗列出来,然后逐步完善代码。

// 默认生成的文件
{
"name": "react-project",
"version": "0.1.0",
"private": true,
"dependencies": {
"@ant-design/icons": "^4.0.6",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@types/jest": "^24.9.1",
"@types/node": "^12.12.36",
"@types/react": "^16.9.34",
"@types/react-dom": "^16.9.6",
"antd": "^4.1.4",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-redux": "^7.2.0",
"react-router-config": "^5.1.1",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"typescript": "^3.7.5"
},
"scripts": { // 下边会更改这个部分
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

目前为止,配置文件内容

{
"name": "react-project-ts",
"version": "0.1.0",
"private": true,
"dependencies": {
"@ant-design/icons": "^4.0.6",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@types/echarts": "^4.4.6",
"@types/jest": "^24.9.1",
"@types/node": "^12.12.36",
"@types/react": "^16.9.34",
"@types/react-dom": "^16.9.6",
"@types/react-redux": "^7.1.7",
"@types/react-router-config": "^5.0.1",
"@types/react-router-dom": "^5.1.4",
"@types/redux-thunk": "^2.1.0", // 以上都是针对ts的
"antd": "^4.1.4", // antd
"babel-plugin-import": "^1.13.0", // 按需加载组件代码和样式的 babel 插件, 对应的是 config-overrides.js
"customize-cra": "^0.9.1", // 加载 less 样式; 配置config-overrides.js
"echarts": "^4.7.0", // 百度图表
"echarts-for-react": "^2.0.15-beta.1", // 百度图表 react版本
"less": "^3.11.1", // less
"less-loader": "^5.0.0", // less 加载
"react": "^16.13.1",
"react-app-rewired": "^2.1.5", // 对 create-react-app 的默认配置进行自定义,更改的是 package.json 中的scripts:start、build、test
"react-dom": "^16.13.1",
"react-redux": "^7.2.0", // react <-> redux
"react-router-config": "^5.1.1", // 路由配置
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"redux": "^4.0.5",
"redux-logger": "^3.0.6", // 日志
"redux-thunk": "^2.3.0", // 异步
"typescript": "^3.7.5"
},
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

总结,这部分主要添加一些所需模块,没啥东西。

⚠️注意事项

疑问1🤔️: 如何按需加载antd组件?

  1. babel-plugin-import:
    1. 目标:按需引用antd
    2. 如何做:antd说明–搜:babel-plugin-import

疑问2🤔️:如何加载less文件??

  1. react-app-rewired
    1. 目标:自定义启动服务
    2. 如何做:antd说明–搜react-app-rewired

针对这两个问题,由于只是配置,仔细看下antd说明完全可以搞定。

本来写了个demo,感觉太简单了,没必要。。。

步骤三 自定义布局

这个部分主要采用antd的布局方式

常规布局,sider、header、 content、footer

侧边栏布局效果如下

整体布局与首页

步骤四 表单页面

表单页面

之后单文件的注意事项会在代码首部写明,便于之后复习。
因为表单页面场景比较多,结合注册登录页面将常规使用、触发,模拟触发交互数据的动作,过程中主要遇到的问题

⚠️注意事项

  1. 函数组件路由如何跳转?

    1. 路由跳转的几种方式:
      1. 路由组件
        1. this.props.history.push()
      2. 非路由组件 ✍️
        1. useHistory: react-router-dom中的hook–useHistory(): 可以获取到history
        2. withRouter: 添加withRouter,参数中包含props
  2. 函数组件中form如何在antion中获取到/验证 form value?

    1. ✍️ 利用Form.useForm(),可以获取到form, 进一步获取到form.validateFields()、form.getFieldValue(‘phone’)
    2. 验证方法
      1. 点击实例代码看控制台
      2. 看代码中的注释

代码链接

这篇文章跨度有点大,但是并不涉及数据流相关操作,故不懂的就看代码吧,里边有注释,其中还有些布局问题,先解决大问题,具体细节之后再修仔补。

之后的章节都会以不同的分支作为与文章对应的代码。

代码

仓库: git@github.com:simuty/react-project.git
分支: origin/chapter1/step2