react+antd 项目笔记
Atwood 定律
Any application that can be written in JavaScript, will eventually be written in JavaScript. (任何能够用JavaScript实现的应用,最终都必将由JavaScript实现。) – Jeff Atwood
记录react学习进程,以及使用 antd
和 react
写 demo
时候遇到的问题。
项目地址:https://github.com/popring/ofo-ms/tree/ofo-ms-js
记录学习React心路历程,以及开发过程中遇到的疑难杂症
React
React 生命周期(按顺序从上往下)
Mounting
lifecycle name | description |
---|---|
constructor | react 组件挂载前会调用它的构造函数 |
componentWillMount | 过时,挂载前调用 |
render | class组件中唯一必须实现的方法,最好为纯函数,代码更加简洁易懂 |
componentDidMount | 组件挂载后调用 |
Updating
lifecycle name | description |
---|---|
componentWillReceiveProps` | 过时,在已挂载的组件接收新的props之前被调用 |
shouldComponentUpdate(nextProps, nextState) | 根据此函数的返回值判断 React 组件的输出是否受当前 state 或 props 更改的影响,默认为true , state 或 props 更新时是否需要重新渲染视图 |
componentWillUpdate | 过时,当组件接收新的props或state时,会在渲染之前调用 |
componentDidUpdate(preveProps, prevState, snapshot) | 组件更新后调用,首先渲染不会被调用 |
Unmounting
lifecycle name | description |
---|---|
componentWillUnmount | 组件卸载及销毁前调用,此方法中执行必要的清除操作(例如:清除定时器,取消网络请求,清除在 componentDidMount() 中创建的订阅) |
组件内部的函数 this
指向问题
多半刚入门
react
的新手都会遇到这个问题,组件内函数this的指向问题
React组件中函数不能直接这么写,调用的时候使用setState会有问题,需要解决this指向问题1
2
3
4
5
6
7
8
9import React from 'react'
export default class Life extends React.Component {
handleBindClick() {
this.setState({
count: this.state.count + 1
})
}
}
解决1, 绑定this指向1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import React from 'react'
export default class Life extends React.Component {
handleBindClick() {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<button onClick={this.handleBindClick.bind(this)}>+1</button>
</div>
)
}
}
解决2, 直接使用箭头函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import React from 'react'
export default class Life extends React.Component {
handleBindClick = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<button onClick={this.handleBindClick}>+1</button>
</div>
)
}
}
State
状态管理1
2
3
4
5
6
7
8
9
10class Example extends React.Component {
// 可以在这里定义
state = {}
constructor(props) {
super(props)
// 也可以在这里定义
this.state = {}
}
}
修改状态
- 不要直接修改
state
,使用this.setState()
state
可能是异步的
React父子之间相互调用
父子间数据传递
父传子
父组件发生变化,值传入子组件,从而重新渲染
子组件接收的为一个值。
1 | // 子组件 |
子传父
父组件
1 | // 子组件 |
Tips: 这样也有明显的缺点,如果父子间传值层数或者值过多,这个方法显然过于麻烦,因此
React
官方给出了解决方法。 Context
调用方法
父调用子方法
1 | class Children extends React.Component { |
子调用父方法
1 | class Children extends React.Component { |
Context
Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
1 | const MyContext = React.createContext(0); |
Fragments
单组件返回多个元素,解决不需要根节点包裹的情况。
段语法1
2
3
4
5
6
7
8
9
10class Columns extends React.Component {
render() {
return (
<>
<td>Hello</td>
<td>World</td>
</>
);
}
}
配置相对路径
配置后 **@**表示根目录下的 src路径,配置
jsconfig
后vscode
提示更加友好
webpack.config.js1
2
3
4alias: {
//...,
'@': path.resolve(__dirname, '../src')
}
jsconfig.json1
2
3
4
5
6
7
8
9
10
11
12
13
14{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"allowSyntheticDefaultImports": true,
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"exclude": [
"node_modules"
]
}
jsconfig 配置详情
Koa
异步延时函数
setTimeout 会被加入异步队列,需使用promise来解决
为此还专门在思否提问
1 | async function delayer(time = 2000) { |
其他
对象的操作
对象的赋值
假设1
2
3
4
5obj1 = {
a: 1,
b: 2,
c: 3
}1
2
3
4obj2 = {
c: 33,
d: 44
}
将对象 obj2
属性的值赋值到 obj1
中的属性 ,相同的属性覆盖,但不修改obj1
的其他值。俗称,浅拷贝1
2
3
4Object.assign(obj1,obj2);
// 或者使用ES6语法,更简单
obj1 = { ...obj1, ...obj2};
判断对象中是否含有某个属性
仍以上面两个对象为例,则1
2
3
4
5// true
obj1.hasOwnProperty('a');
// false
obj2.hasOwnProperty('a');
过滤对象属性
props: 原对象
arr: 需要过滤掉的键
newProps: 过滤后剩下的键值组成的对象
1 | const props = { |
操作函数拆分解释
Object.keys(obj)
返回 由 obj 的键组成的数组
Array.prototype.filter
数组过滤的方法,传入的函数中的返回值为 true 则过滤,为 false 则留下。返回一个新数组,不会改变原数组。
Array.prototype.includes()
判断数组内是否包含指定的值。包含返回 true,反之 fales。
forEach
遍历对象和数组。