react类组件
创建 Class 组件
ES6 方式
1
2
3
4
5
6
7
8
9
10
11import React from 'react'
class B extends React.Component{
constructor(props){
super(props)
}
render(){
return (<div>hi</div>)
}
}
export default B
ES5 方式(过时)
1
2
3
4
5
6
7
8
9import React from 'react'
const A = React.createClass({
render(){
return(<div>hi</div>)
}
})
export default A
// 由于 ES5 不支持 class,才会有这种方法
props
传入 props 给 B 组件
1 | class Parent extends React.Component { |
###初始化
1 | class B extends React.Component{ |
读取
1 | class B extends React.Component{ |
props 的作用
接受外部数据
- 只能读不能写
- 外部数据由父组件传递
接受外部函数
- 在恰当的时机,调用该函数
- 该函数一般是父组件的函数
state & setState
初始化
1 | class B extends React.Component { |
读写 State
读 this.state
this.state.user.name
写 this.setState(???,fn)
this.setState(newState, fn)
注意 setState 不会立刻改变 this.state,会在当前代码运行完后,再去更新 this.state,从而触发 UI 更新。(异步)
this.setState((state, props) => newState, fn)
这种方式的 state 更容易理解
fn 会在写入成功后执行。
shallow merge: setState 会自动将新的 state 与 旧的 state 进行一级合并。
1 | onClick = () => { |
修改 this.state 的属性值,不推荐用!
1 | this.state.x += 1 |
生命周期
类比如下代码
1 | let div = document.createElement('div') |
函数列表
constructor()
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidMount()
componentDidUpdate()
componentWillUnmount()
static getDerivedStateFromError()
componentDidCatch()
函数列表-必会
constructor()
- 在这里初始化 state
shouldComponentUpdate()
- return false 阻止更新
render()
- 创建虚拟 DOM
componentDidMount()
- 组件已出现在页面
componentDidUpdate()
- 组件已更新
componentWillUnmount()
- 组件将死
constructor
用途:
初始化 props
初始化 state,但此时不能调用 setState
用来写 bind this
1 | constructor(){ |
可以用新语法代替
1 | constructor(){...} |
shouldComponentUpdate
用途:
返回 true 表示不阻止 UI 更新
返回 false 表示阻止 UI 更新
面试常问:shouldComponentUpdate 有什么用?
答:它允许我们手动判断是否要进行组件更新,我们可以根据应用场景灵活地设置返回值,以避免不必要地更新。
1 | import React from "react"; |
可以使用 React.PureComponent
替代 React.Component
实现 shouldComponentUpdate()
PureComponent 会在 render 之前对比新 state 和旧 state 的每一个 key,以及新 props 和旧 props 的每一个 key。
如果所有 key 的值全都一样,就不会 render;如果有任何一个 key 的值不同,就会 render。
注意
React.PureComponent
中的shouldComponentUpdate()
仅作对象的浅层比较。如果对象中包含复杂的数据结构,则有可能因为无法检查深层的差别,产生错误的比对结果。仅在你的 props 和 state 较为简单时,才使用
React.PureComponent
。
render
用途:
展示视图 return (<div> ... </div>)
,只能有一个根元素。
两个根元素,要用 <React.Fragment>
包起,可以缩写为 <> </>
技巧:
render 里面可以写 if...else
、?:
表达式
不能直接写 for
循环,需要用数组
render 里面可以写 aray.map
(循环)
1 | class App extends React.PureComponent { |
componentDidMount()
用途:
在元素插入页面后执行代码,这些代码依赖 DOM
比如,想获取 div 的高度,最好在这里写。
此处可以发起加载数据的 Ajax 请求(官方推荐)
首次渲染 会执行此钩子
1 | // 想获取 div 的高度 |
改用 ref
1 | class App extends React.PureComponent { |
componentDidUpdate()
用途:
在视图更新后执行。第一次渲染不执行。
此处也可以发起 Ajax 请求,用于更新数据 (文档)。
首次渲染不会 执行此钩子。
在此处 setState 可能会引起无限循环,除非放在 if 里。
若 shouldComponentUpdate 返回 false,则不会触发此钩子。
componentWillUnmount()
用途:
组件将要 被移出页面 然后被销毁 时执行代码
unmount 过的组件不会再次 mount
举例:
如果你在 c…DidMount 里面监听了 window scroll
那么你就要在 c…WillUnmount 里面取消监听
如果你在 c…DidMount 里面创建了 Timer
那么你就要在 c…WillUnmout 里面取消 Timer
如果你在 c…DidMount 里面创建了 Ajax 请求
那么你就要在 c…WillUnmount 里面取消请求
否则你就是菜逼。
生命周期回顾
constructor()
- 在这里初始化 stateshouldComponentUpdate()
- return false 阻止更新render()
- 创建虚拟 DOMcomponentDidMount()
- 组件已出现在页面componentDidUpdate()
- 组件已更新componentWillUnmount()
- 组件将死