初始化项目
create-react-app demo-name --template typescript
配置 craco,不推荐eject,可以去antdesign官网查看
yarn add @craco/craco @alpha -D
创建craco.config.js
const path=require("path")
const resolve=(dir)=>path.resolve(_dirname,dir)
module.exports={
webpack{
alias:{
"@":resolve("src")
components:resolve("components") //可配可不配
}
}
}
ts.config配置
"baseUrl":"",
"paths":{
"@/*":[
"src/*"
]
}
packge.json 配置成craco build craco test craco start
代码规范
.editourconfig
# 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
npm install prettier -D
.perttierrc
{
"useTabs": false,
"tabWidth": 2,
"printWidth": 80,
"singleQuote": true,
"trailingComma": "none",
"semi": false
}
可以在packge.json配置命令 “prettier”:“prettier --write .”
.prettierigonore
/build/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*
eslint
npm install eslint -D
npx eslint --init // check 2 modules 1 react yes 选中node敲回车全选,先选浏览器,js ,yes,npm
在配置文件env内添加node:true,表示也可以跑在node环境,避免使用commonjs报错 ,不希望他报错的,只需要把错误提示粘贴到rules里值为‘off'
prettier和eslint风格保持一致
npm install eslint-plugin-prettier eslint-config-prettier -D
在eslint配置文件内加入 extends=>'prettier:prettier/recommended'
module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended'
],
overrides: [],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module'
},
plugins: ['react', '@typescript-eslint'],
rules: {
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off'
}
}
出问题第一个设置vscode配置文件
"eslint.lintTask.enable": true,
"eslint.alwaysShowStatus": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
normalize.css,less查看ant-design,npm i craco-less@2.1.0-alpha.0
路由
npm i react-router-dom配置文件单独抽离,使用useRouter引入,注意man.ts要加入HashRouter
包裹,路由才能生效。单个路由的类型为RouteObject
Ts组件注意点,除了直接给函数式组件的props定义类型,也可以给组件直接定义类型,使用泛型来约束props,组件类型为React.FunctionComponent<PropsType>算是另外一种写法React.FC<>泛型内指定即可,或者直接导入FC也行
区别在于写FC指定,在给组件的属性赋值的时候有更好的提示,和更好的错误检测,以前这种方式自带children,现在没有,自己指定ReactNode类型,可选。随后函数式组件memo包裹,模板可以使用${1:home}占位,路由需要懒加载const compontName=lazy(()=>import("path")),index.jsx需要Suspense fallback=“loding”,这也也可以在加载的时候显示一个组件,二级路由 <OutLet/>占位,只要路由最好都加上Suspense,避免闪烁
状态管理
npm i @reduxjs/toolkit react-redux,index中使用provider提供store,如何指定useSelector中state的类型。我们本质上是拿到对应store.getstate的类型,这是一个函数,我们可以通过typeof拿到对应的类型,在通过ReturnType<>来拿到对应的返回值类型,但是很麻烦,一种方案是在store类直接暴露类型,我们可以在store中将selector,赋值给自己的变量,随后导出,如何指定类型呢,TypeUseSelectorHook
当前操作在reduxtoolkit的configureStore中
type userstoretype=typeof store.getstate //这个store就是我们configureStore的返回值,getstate本身是获取值的,同时他是一个方法,所以会由包含返回值类型
export type Irootstate=ReturnType<userstoretype>
export const useAppselector:TypeUseSelectorHook<Irootstate>=useSelector
本质上这是个调用签名,redux是由说明的
useDispatch也可以定制 export const Appdispatch:()=> typeof store.dispatch=useDispatch
扩展ts TypeUseSelectorHook说明
interface foo{
<T>(fn:()=>T):string
}
这个函数被调用的时候这个泛型会被传入, 这里我们没有传入,但是他会自动推导
环境变量区分导入axios
process.env.NODE_ENV这个变量的值就是环境值,项目构建后build,可以直接使用serve,需要安装 serve,serve -s build,部署后环境变量就会被更改,或者创建配置文件,动态加载.env.development和.env.production 变量前缀REACT_APP_BASE_URL在vite是VITE_,我们在config中使用precession.env.变量名
TS
类组件的类型定义了解即可
import React,{Pureconmponent} from 'react'
interface Iprops{
}
interface IState{
name:string
}
class Demo extends purrecomponent<Iprops,IState> {
//优化部分,这里的state会自动推导类型,这样子构造可以不用写,他会默认superprops,purecomponent接受三个泛型,最后约束的是返回值,getSnapshotBeforeUpdate的返回值
state:{
}
constructor(props:Iprops){
super(props)
this.state={
name:"xx"
}
}
render(){
return (<div>{this.state.name}</div>)
}
}
store的pyload也可以指定类型,action指定{ payload }:PayloadAction<string>
CSS
引入styled-components,
注意项 ref是ElementRef<typeof Carous(组件名称)l>(null),拿到实例方法是通过current