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 生命周期总结
























![[桜井宁宁]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)
