react04(类组件生命周期钩子)

173 阅读3分钟

创建class组件

ES6

import React from 'react'
class B extends React.Component
{
constructor(props);
super(props);
}
render(){
return (
	<div>hi</div>
)
}
export default B;

Props(外部数据)

prop外部数据

  • 传入props给B组件
class Parent extends React.Component{
constructor(props){
super(props)
this.state = { name:'mamami'}
}
onClick = () => {}
render(){
return <B name = {this.state.name} onClick={this.onClick}>hi</B>
}
}
//外部数据被包装为一个对象
//{name: 'mamami',onClick:...,children:'hi'}
//此处的onClick是一个回调

初始化:

class B extends React.Component{
constructor(props){
super(props);
}
render(){}
效果: 这么做了之后this.props就是外部数据对象的地址了

读取

class B extends React.Component{
constructor(props){
super(props);
}
render(){
return <div onClick={this.props.onClick}>{this.props.children}</div>
<div> { this.props.children}</div>
}
}// 通过 this.props.xxx读取

写props

  • 改props的值(一个地址)
  • this.props ={/另一个对象/}
  • 不要写这样的代码,没有意义
  • 理由:既然是外部数据,就不因该在内部修改。

原则

  • 因该由数据的主人来修改。

相关钩子函数

comppnentWillReceiveProps钩子

  • 当组件接收新的props,会触发此钩子

props的作用

接受外部数据

  • 只能读不能写
  • 外部数据由父组件传递

接受外部函数

  • 在恰当的时机,调用改函数
  • 该函数一般是父组件的函数

State & setState (内部数据)

初始化State

class B extends React.Component{
constructor(props){
super(props);
this.state = {
user: {name:'mamami',age:200}
}
}
render(){*/ ...  */ }
}

读写State

  • 读用this.stat
  • this.state.xxx.yyy.nnn
  • 写用this.setState(???,fn)
  • this.setState(newState,fn)
  • 注意se不会立刻改变this,Stat.state,会在当前代码运行完后,再去更新this.state,从而触发ui更新
  • this.setState((state,props)=>newState,fn)
  • fn会在写入成功后执行

写时会shallow merge

  • setState会自动将新state与旧state进行一级合并 注意: 修改this.state的属性值this.state.n+=1不建议使用

生命周期

类比如下代码

// 这是div的create/construct过程
div.textContent = 'hi'
// 这时初始化state
document.body.appendChild(div)
//这是div的mount过程
div.textContent = "h2" 
//这是div的update过程
div.remove()
//这是div的unmount过程

同理

  • react组件也有这些

函数列表

  • constructor()-在这里初始化state
  • shouldComponentUpdate()-return false阻止更新
  • render() -创建虚拟DOM
  • componentDidMount() -组件已经出现在页面
  • componentDidUpdate() -组件已经更新
  • componentWillUnmount() -组件即将消失

constructor

  • 用途
  • 初始化props
  • 初始化state,但此时不能调用setState
  • 用来写bind this
constructor(){
/* 其他代码略*/
 this.onClick =this.onClick.bind(this)
}
可以用新语法代替
onclick = () =>{}
constructor(){/**/}

shouldComponentUpdate

用途

  • 返回true表示不阻止ui更新
  • 返回false表示阻止ui更新 代码
class App extends React.Component{//这里可以改为React.PureComponent就可以不适用这个钩子监听了

    constructor(props) {
        super(props);
        this.state = {
            n: 1,
        }
    }
   onClick= () =>{this.setState(state=>({
          n : state.n + 1
}))
       this.setState(state=>({
           n : state.n - 1
       }))
    };
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        return nextState.n !== this.state.n;
    }

    render() {
        console.log("render了一次")
       return (
           <div>
               {this.state.n}
               <button onClick={this.onClick}>+1</button>
           </div>
       )

}}

render

  • 用途
  • 展示视图return (<div>..</div>)
  • 只能由一个根元素
  • 如果由两个根元素就要用<React.Fragment>包起来
  • <React.Fragment/>可以缩写为<></>

技巧

  • render 里面可以写if..else
  • render里面可以写?:表达式
  • render里面不能直接写for循环,需要用数组
  • render里面可以写array.map(循环)

componentDidMont()

用途

  • 在元素插入页面后执行代码,这些代码依赖dom
  • 比如你想获取div的高度,就最好在这里写
  • 此处可以发起加载数据的AJAX请求(官方推荐)】
  • 首次渲染执行该钩子 具体参数看官方文档

componentDidUpdate()

  • 用途
  • 在视图更新后执行代码
  • 此处也可以发AJAX请求,用于更新数据|
  • 首次渲染不会执行该钩子
  • 在此处setState可能会引起无线循环,除非放在if里
  • 若shouldCom...Update返回false,则不会触发此钩子 参数看文档

ComponentWillUnmount

用途

  • 组件将要被移除页面然后被销毁时执行的代码

举例

  • 如果你在c...DidMount里面监听了window scroll,那么你就要在c..willUnmount里面取消监听

分阶段看钩子执行顺序