安装
npx create-react-app my-app --template typescript
yarn create react-app my-app --template typescript
yarn
npm i
npm install --save react-router-dom
yarn run eject
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)]
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: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'less-loader'
),
sideEffects: true,
},
{
test: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'less-loader'
),
},
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KuhNto5t-1585184487771)(https://i.loli.net/2020/03/05/RSLznh92xbQGsqk.png)]
安装 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
做成后台公共组件的形式,需要把 登录页面 和 错误页面暴露出去;这时候遇到问题,两种解决方案。
- 将404、500等报错页面放到公共组件下面。
- 每个路由包一层layout,单独放 login 和 404、500等报错页面。
使用withRouter 报错
一个资深大神给的建议:说 mobx 和 react-router-dom 这两个包不兼容的时候,使用any;就可以了。如下:
@(withRouter as any)
antd 4.x 版本icon 变成按需引入
antd 4.x 版本icon 变成按需引入,icon不能一次全部加载进去,下面 是解决方案。
安装 mobx
使用Mobx作为app状态管理方案
记得安装 MobX Developer Tools
mobx 开发 谷歌插件
npm install --save mobx mobx-react
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 用法示例
- 在
src
下建立stores
文件夹。并依次建立detail.ts
,index.ts
。
reatc-example
├── src
│ ├── stores
│ │ │── detail.ts
│ │ └── index.ts
│ └── index.tsx
├── config
│ └── webpack.config.js
└── package.json
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)
}
}
index.ts
文件,store的初始化
import HomeStore from './home'
import DetailStore from './detail'
export default {
homeStore: new HomeStore(),
detailStore: new DetailStore(),
}
- 配置Provider 在
src/index.tsx
下
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'mobx-react'
import Router from './router/router';
import stores from './stores/index';
ReactDOM.render(
<Provider {...stores}>
<Router />
</Provider>,
document.getElementById('root'));
- 使用store
注意这里 在react 中,会用到装饰器,而装饰器写法只能在 class 类组件中使用。而 函数式组件 只能 使用嵌套的方式。
一、 第一种 class 组件中。
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 {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
指向问题。如下面的例子:
@action
public setName(name: string) {
this.name = name
}
private clickHandler = (): void => {
const {setName}=this.props.homeStore
setName("Bob666")
}
@action
public setName = (name: string) => {
this.name = name
}
private clickHandler = (): void => {
const {setName}=this.props.homeStore
setName("Bob666")
}
二、 第二种 函数 组件中
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
- 安装
js-cookie
npm i js-cookie @types/js-cookie --save
- 使用 fetch
- Fetch
在utils/request-fetch.ts
文件夹下
打包
npm run build
但是 会生成.map文件
;上线的时候我们需要去掉这个文件。
在config/webpack.config.js
内 第33行
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
直接将改为
const shouldUseSourceMap = 'false';
即可。
第二种办法,由上面的信息可知,.map
文件是由回家变量process.env.GENERATE_SOURCEMAP
控制的。所以由于打包的时候执行的脚本文件是scripts/build.js
,所在在scripts/build.js
内添加如下代码即可。
process.env.GENERATE_SOURCEMAP = 'false';
报错
- 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
只能使用一种方式。
- 在
pages/login/components/LoginForm.tsx
中引入store会报错。
Instance created by
useFormis not connect to any Form element. Forget to pass
formprop?
报错
- https://github.com/ant-design/ant-design/issues/21543
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)