1.工具:搭建React项目的脚手架

  • create-react-app 项目名称

如果采用create-react-app 项目名称的方式搭建脚手架则生成的项目中不含TS配置需要自己手动搭建TS配置。存在的弊端如下:

  • 弊端一:项目基于webpack,webpack所有配置是隐藏的
  • 弊端二:TS React项目配置难度较大。并且将ts代码转化成js代码的编译方式有TS Compiler和Lable两种方式,两者最好都要配置,难度较大。
  • **create-react-app 项目名称 –template typescript **—>利用git bash窗口创建,如果利用黑窗口前面加npm或npx

上面脚手架配置的好处:

  • create-react-app:创建了一个react项目
  • 后面内容的存在同时配置TS的支持

2.项目配置

  • 配置项目的icon
  • 配置项目的标题
  • 配置项目别名等(craco.config.ts)—>配置src的别名放置出现多个../../的嵌套

因为别名的配置是基于webpack配置的,它的东西又被隐藏了,所以需要借助craco:create-react-app config。因为react5.0版本太新,所以在安装craco的时候也需要安装最新版本 npm install @craco/craco@alpha -D

  • 配置tsconfig.json

  1. 配置项目别名步骤
    1. 安装craco

如果react采用的是4.0版本采用 npm install @craco/craco -D
如果react采用的是5.0版本使用 npm install @craco/craco@alpha -D

  2. 创建craco.config.js文件

在根目录下即src外层创建该文件;

  3. 配置文件内容

__dirname:当前目录;
craco.config.js文件内容代码配置如下:
image.png
然后在tsconfig.json文件里配置路径的相关内容,否则在其他文件中无法使用image.png
并且将package.json中前三个的react-script改成craco,进行合并使用,否则在编译生成页面的时候仍会报错
image.png


3.代码规范

集成editorgonfid配置

editorConfig配置有助于为不同的IDE编译器上处理同一个项目的多个开发人员维护一致的编码风格。
新建.editorconfig文件,无后缀

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# http://editorconfig.org

root = true

[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行尾的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行

[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false

prettier

prettier保持代码的某一种风格,格式化代码,使其更加美观

  1. 安装prettier:  npm install prettier -D
  2. 在项目的根目录下创建.prettierrc文件
  3. 测试prettier是否生效
     - 在代码中保存代码;
     - 配置一次性修改的命令

在package.json中配置一个script

1
"prettier":"prettier --writer ."

可以输入命令手动格式化所有未被忽略的文件:

1
npm run prettier

1.4**.忽略不被格式化的文件**

  • 在根目录下创建.prettierignore文件
  • 在文件中写入要忽略的文件
1
2
3
4
5
6
7
8
9
# /build/*
# .local
# .output.js
# /node_modules/**

# **/*.svg
# **/*.sh

# /public/*

使用EsLint检测
  1. 安装eslint:  npm install selint -D
  2. 由于eslint的配置比较多所以采用命令的方式自动生成配置文件
  • 对eslint进行初始化:npx eslint –init
  • 输入y生成配置文件
  • 在三个选项中选择第二个,检测错误并发现问题,第三个选项多个一个强制代码转换,由于上面配置过prettier所以不需要
  • 选择第一个js模块化

image.png

  • 因为这个项目是React项目所以选择React
  • 因为使用了TS所以是yes
  • 选择浏览器Browser;选择js文件;选择yes;选择npm

image.png
1.3 修改生成的配置文件
由于上方生成的配置文件只选择在浏览器环境下运行,而项目中又参杂了node所以为了保证可以在node环境下进行,需要在配置文件的“env”里加入:

1
"node":true

为了使require正常使用要在配置文件的rules中加入如下代码:

1
'@typescript-eslint/no-var-requires': 'off'

1.4 vsCode需要安装eslint插件
1.5解决eslint和prettier冲突的问题:
安装插件:(vue在创建项目时,如果选择prettier,那么这两个插件会自动安装。
npm install eslint-plugin-prettier eslint-config-prettier -D
安装成功之后在.eslintrc.js中增加下方代码:使eslint与prettier代码风格一致。

1
'plugin:prettier/recommended'

prettier和eslint存在冲突,暂时不要用尤其是eslint;

4.项目目录结构的划分

  • assets放置静态资源:例如:css,img
  • base-ui多个项目使用的共同组件
  • components:存放当前项目中多出使用到的共同组件
  • hook:自定义hook———–>一般不单独建文件夹
  • router
  • store
  • service:网络请求
  • utils:存放工具,例如:全局自定义弹窗
  • views:存放视图,展示不同页面的组件

5.对CSS样式的重置

  • normalize.css: npm install normalize.css

在tsx文件中引入normalize.css,从而对默认的css进行重置

  • reset.less:自己在静态文件夹下的css文件中建立文档,定义 jk重置的css样式

如果使用less需要安装指定版本:
npm install craco-less@2.1.0-alpha.0

6.路由的配置

  1. 路由的搭建:npm install react-router-dom
  2. 在写路由的时候与vue使用compoent不同的是React用的element,并且element后面跟的是组件实例(<Discover />)而非Discover。由于组件实例属于jsx语法,所以写路有的文件不能是.ts应该是.tsx。凡是tsx文件都需要引入React(import React from 'react')。
  3. 如果使用路由,最外层的index.tsx中的APP必须被router包裹
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from "react";
import ReactDOM from "react-dom/client";
import { HashRouter } from "react-router-dom";
import "normalize.css";
import "./assets/css/index.less";
import App from "@/App";

const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<HashRouter>
<App />
</HashRouter>
);
1.4:写路由组件的一般做法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import React,{memo} from "react";
import type { ReactNode } from "react";
//如果想要读取组件中包括的子组件需要定义children,因为props本身中没有children,不能直接读取传入的子组件
interface IProps {
children?: ReactNode; //传入children写,不传则去掉
name: string;
age: number;
height?: number;
}
//方式一:直接对props进行类型约束:props:IProps
// const Download = (props: IProps) => {
// return (
// <div>
// <div>name:{props.name}</div>
// <div>age:{props.age}</div>
// <div>height:{props.height}</div>
// </div>
// );
// };

//方式二:借助ts泛型
const Download: React.FC<IProps> = (props) => {
return (
<div>
<div>name:{props.name}</div>
<div>age:{props.age}</div>
<div>height:{props.height}</div>
<div>{props.children}</div>
</div>
);
};

//最好使用memo函数,它的导出性能比较好
// export default Download;
export default memo(Download)

1.5react与vue二级路由的不同之处:

  • vue的二级路由的path不用加一级路由的路径
  • react的二级路由的path需要加一级路由的路径否则会报错(如:/discover/recommend)

7.配置react基本代码的一键生成模板

已知tsx文件基础的模板代码格式如下:

1
2
3
4
5
6
7
8
9
import React, { memo } from "react";
import type { FC, ReactNode } from "react";
interface IPprops {
children?: ReactNode;
}
const Djradio: FC<IPprops> = () => {
return <div>Djradio</div>;
};
export default memo(Djradio);

利用工具自动生成代码时将可变的文件名称(如:Djradio)改成${1:Home},生成的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"react typescript": {
"prefix": "tsreact",
"body": [
"import React, { memo } from \"react\";",
"import type { FC, ReactNode } from \"react\";",
"interface IPprops {",
" children?: ReactNode;",
"}",
"const ${1:Home}: FC<IPprops> = () => {",
" return <div>${1:Home}</div>;",
"};",
"export default memo(${1:Home});"
],
"description": "react typescript",
}

点击Vscode->文件->首选项->配置用户片段代码->输入Typescriptreact->将得到的代码粘贴
因为上方代码的prefix的值时tsreact所以在一个新的tsx文件中输入tsreact回车会自动生成react的基础代码。

8.状态管理

状态管理选择:

  • redux:目前React中使用最多的状态管理库;
  • @reduxjs/toolkit:redux工具,更方便的使用redux

操作:
不需要单独安装redux,只需要如下步骤:
npm insatll @reduxjs/toolkit react-dom
接着在store文件夹中创建index.ts文件,编写store内容:

1
2
3
4
5
6
7
import { configureStore } from "@reduxjs/toolkit";

const store = configureStore({
reducer: {},
});

export default store;

在最外层的index.tsx文件中导入store和Provider,Proviindex.tsxder标签位于最外层,使其他页面可以利用store。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React from "react";
import ReactDOM from "react-dom/client";
import { HashRouter } from "react-router-dom";
import { Provider } from "react-redux";
import "normalize.css";
import "./assets/css/index.less";
import App from "@/App";
import store from "./store";

const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<Provider store={store}>
<HashRouter>
<App />
</HashRouter>
</Provider>
);

如果想要保存数据可以在store中创建一个文件夹modules,然后在其下面新建一个ts文件(如counter.ts文件)。在这个文件中及时initalState(初始化)和reducers中无内容也要书写,因为他们和name是必写内容,否则会报错。

1
2
3
4
5
6
7
8
9
10
11
import { createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: {
count: 100,
message: "Hello Redux",
},
reducers: {},
});

export default counterSlice.reducer

然后导出的内容需要放在store里面否则无效。

1
2
3
4
5
6
7
8
9
10
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counter";

const store = configureStore({
reducer: {
counter: counterReducer,
},
});

export default store;

9.网络请求封装axios

  1. 安装axios

npm install axios
由于最新班的axios版本过高会有报错,所以安装1.1版本
npm install axios@1.1.0

  2. 1
     <a name="sFgV1"></a>

10.如何打包项目:

  1. npm run build
  2. 打包完成之后在本地跑起来:npm install -g serve
  3. 启动服务器以build作为资源:serve -s build
     <a name="blAiO"></a>

11.css-in-js库

react是用js写html的框架,为了在react框架中使用js编写一切代码,使用css-in-js库编写css代码,style-components是近期使用人数最多的css-in-js库,它的优点如下:

  • 可以编写实际的CSS代码来设计组件样式,也不需要组件和样式之间的映射,即创建后就是一个正常的React 组件,直接在JSX中引入即可
  • 在一个组件内会将结构、样式和逻辑写在一起,虽然这违背了关注点分离的原则,但是这有利于组件间的隔离。为了顺应组件化的潮流
  • 使用styled-components不需要再使用className属性来控制样式,而是将样式写成更具语义化的组件的形式
  • 使用style-components会随机生成一个class名称,这样不会污染到全局变量,当然因为随机生成,维护会增加难度

使用步骤:

  • 安装style-components:npm install styled-components -D
  • 在引入和使用styled-components之前需要先对其进行类型声明否则会报错。

类型声明的几种形式:

  • typescript内置DOM
  • 第三方:
    • 库内部已经有类型声明(eg:axios)
    • react/react-dom=>@types/react @types/react-dom
    • 自己写的类型声明
  • 解决方式: npm i –save-dev @types/styled-components

12.react的第三方库-antd

  • 安装antd:npm install antd –save
  • 如果想要使用图标需要单独再安装一个图标库:npm install –save @ant-design/icons

13.动态添加classname

安装classname库,当利用map之类动态数据遍历的时候可以动态添加classname
npm install classname