1 创建Class组件
-
ES5方式(过时)
import React from 'react' const A = React.createClass({ render(){ return( <div>hi</div> ) } }) export default A 复制代码 -
ES6方式
import React from 'react' class B extends React.Component { constructor(props){ super(props); } render() { return ( <div>hi</div> ) } } export default B 复制代码
2 Props外部数据
-
传入props给B组件
import React from 'react' class Parent extends React.Component { // 初始化 this.props就是外部数据对象的地址了 constructor(props){ super(props); // 父元素的state作为props this.state = {name : 'frank'} } onClick = () => {} render() { return ( {/* 把this.state.name作为B的外部数据 */} < B name = {this.state.name} {/* 把外面的onClick函数传给B的onClick,此处的onClick是一个回调 */} onClick = {this.onClick}>hi</B> ) } } // {name: 'frank', onClick: ... , children: 'hi'} export default B 复制代码 -
读props
class B extends React.Component{ constructor(props){ super(props); } render(){ return <div onClick = {this.props.onClick}> {this.props.name} <div> {this.props.children} </div> </div> } } // 通过 this.props.xxx读取 复制代码 -
写props
原则上应该由数据的主人对数据进行更改
-
props的作用
-
接受外部数据
只能读不能写
外部数据由父组件传递
-
接受外部函数
在恰当的时机,调用该函数
该函数一般是父组件的函数
-
3 State 内部数据
-
初始化State
class B extends React.Component{ constructor(props){ super(props); this.state = { user:{name : 'frank', age : 18} } } render() {} } 复制代码 -
读写State
-
读用this.state
this.state.xxx.yyy.zzz 复制代码 -
写用this.setState(???, fn)
-
this.setState(newState, fn)注意setState不会立刻改变this.state,会在当前代码运行完后,再去更新this.state,从而触发UI更新
-
this.setState((state,props) => newState,fn)易于理解,fn会在写入成功后执行
onClick = () => { this.setState({ x: this.state.x + 1 }) } onClick2 = () => { this.setState((state) => ({x: state.x + 1})) } 复制代码 -
-
4 生命周期
-
类比如下代码
let div = document.createElement('div') // 这是div的create/construct的过程 div.textContent = 'hi' // 这是初始化state document.body.apppendChild(div) // 这是div的mount过程 div.textContent = 'hi2' // 这是div的update过程 div.remove() // 这是div的numount过程 复制代码 -
生命周期函数列表
constructor()– 在这里初始化statestatic getDerivedStateFroProps()
shouldComponentUpdate()– return false 阻止更新render()– 创建虚拟DOMgetSnapshotBeforeUpdate()
componentDidMount()– 组件已出现在页面componentDidUpdate()– 组件已更新componentWillUnmount()– 组件将死static getDerivedStateFromError()
componetDidCatch()
4.1 constructor
-
用途
-
初始化props
-
初始化state,但此时不能调用setState
-
用来写bind this
constructor(){ ... this.onClick = this.onClick.bind(this) } 复制代码新语法
onClick = () => {} constructor(){...} 复制代码
-
-
可不写
4.2 shouldComponentUpdate
-
用途
返回true表示不阻止UI更新
返回false表示阻止UI更新
-
面试常问
- shouldComponentUpdate有什么用
- 答:它允许我们手动判断是否要进行组件更新,我们可以根据应用场景灵活地设置返回值,以避免不必要的更新
-
示例
import React from 'react' class App extends React.PureComponent { // 1.初始化 constructor(props) { super(props) // 2.设置变量 this.state = { n: 1 } } // 3. 让n+1又-1,UI不会变化,但是每次点击按钮都render了一次 onClick = () =>{ this.setState(state => ({ n: state.n + 1 })) this.setState(state => ({ n: state.n - 1 })) // {n:1} 和 {n:1} 是不同的对象,但值一样 } // 比较新旧n是否改变 // shouldComponentUpdate(nextProps, nextState) { // return nextState.n !== this.state.n; // 返回true不阻止UI更新 // 返回false阻止UI更新 // } render() { console.log('render 了一次') return( <div>App <div> {this.state.n} <button onClick={ this.onClick }>+1</button> </div> </div> ) } } export default App; 复制代码

-
可用PureComponent代替这个钩子
class App extends React.PureComponent{} 复制代码- PureComponent 会在 render 之前对比新 state 和旧 state 的每一个 key,以及新 props 和旧 props 的每一个 key。
- 如果所有 key 的值全都一样,就不会 render;如果有任何一个 key 的值不同,就会 render。
4.3 render
-
用途
展示视图,
return (<div>...</div>)只能有一个根元素,如果有两个根元素,就要用
<React.Fragment>包起来,可以缩写成<></> -
技巧
- render里面可以写if. else
- render里面可以写?:表达式
- render里面不能直接写for循环,需要用数组
- render里面可以写 array map(循环)
render() {
return (
<>
{this.state.n % 2 === 0 ?
<div>偶数</div> : <span>奇数</span>
}
<button onClick={this.onClick}>+1</button>
</>
)
}
复制代码
4.4 componentDidMount
组件已经挂载了
- 用途
- 在元素插入页面后执行代码,这些代码依赖DOM,比如想获取div的高度,最好在这写
- 此处可以发起加载数据的AJAX请求(官方推荐)
- 首次渲染会执行次钩子
- 示例
import React from 'react'
class App extends React.PureComponent {
divRef = undefined
constructor(props) {
super(props)
this.state = {
n: 1,
width: undefined
}
this.divRef = React.createRef()
}
componentDidMount() {
const div = this.divRef.current
const {width} = div.getBoundingClientRect()
this.setState({width})
}
render() {
return (
<div ref={this.divRef}>hello,{this.state.width}px</div>
)
}
}
export default App;
复制代码
4.5 componentDidUpdate
- 用途
- 在视图更新后执行代码
- 此处也可以发起AJAX请求,用于更新数据
- 注意
- 首次渲染不会执行此钩子
- 在此处setState可能会引起无限循环,除非放在if里
- 若
shouldComponentUpdate返回false,则不触发此钩子
4.6 componentWillUnmount
-
用途
组件将要被移出页面然后被销毁时执行代码
unmount过的组件不会再次mount
-
举例
-
如果在componentDidMount里面监听了window scroll,那么就要在componentWillUnmount里取消监听
-
如果在componentDidMount里面创建了AJAX请求,那么就要在componentWillUnmount里取消请求
-
4.7 生命周期总结









![安卓WPS Office[12.5.1]去广告绿色版-一一网](https://www.proyy.com/skycj/data/images/2020-12-14/e8601af1c5ae431aa787d0039b10df11.png)













![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)