react 生命周期钩子函数

state

页面数据定义:用于在当前页面需要使用的数据定义。
与props的区别: props是由父组件传给子组件的属性传值。不可改变,只可以使用,而state是可以通过setState方法来进行改值,并且state的改变会引起render方法的触发,页面会进行重新渲染,所以通常我们会在声明周期中或者事件中对其进行操作。

//在类组件中的使用方法
	// state = {
    //     name: 'zhangsan',
    //     age: 16
    // }
    constructor () {
        super()  //如果需要在构造器中设置state,那么就必需要用该命令。它是和extends配套使用的,它在这里表示父类的构造函数,用来新建父类的 this 对象super()相当于Parent.prototype.constructor.call(this)
        this.state = {
            name: 'zhangsan',
            age: 16
        }
    }
    addAge() {
        this.setState({
            age: ++this.state.age
        })
    }
    subAge() {
        this.setState({
            age: --this.state.age
        })
    }
    render() {
        return (            
            <div>
                类组件
                <h1> {this.state.name} </h1>
                <h1> {this.state.age} </h1>
                <button onClick={this.addAge.bind(this)}>增加年龄</button>
                <button onClick={this.subAge.bind(this)}>减少年龄</button>
            </div>
        )
    }

//函数组件由于没有this所以数据定义方式也不同。
import React,{ useState } from 'react'
export default function Login() {
    const [name, setName] = useState('lisi')
    const [age, setAge] = useState(18)
    const addAge = () => {
        setAge(age + 1)
    }
    const subAge = () => {
        setAge(age - 1)
    }
    return (
        <div>
            函数组件
            <h1> {name} </h1>
            <h1> {age} </h1>
            <button onClick={addAge}>增加年龄</button>
            <button onClick={subAge}>减少年龄</button>
        </div>
    )
}

值得注意的是this.setState()方法是一个异步函数,通常,第一个参数为一个对象,而第二个参数则为一个回调函数,在回调函数中会取到设置的新值,而在方法外面是不能马上获取到新设的值。如果想要将其修改为一个同步的话,我们可以使用一个setTimeOut()或者使用promise进行封装。

addAge() {
        this.setState({
            age: this.state.age + 1
        },() => {
            console.log(this.state.age)
        })
        console.log(this.state.age)
    }

在这里插入图片描述
可以看出执行顺序实现执行同步代码,后执行异步。
在进行setTimeOut过后

addAge() {
        setTimeout(() => {
            this.setState({
                age: this.state.age + 1
            },() => {
                console.log(this.state.age)
            })
            console.log(this.state.age)
        },0)        
    }

在这里插入图片描述
这样就可以实现同步了。
原理:主要是利用了js运行机制,为了解决单线程运行的缺陷,将任务分为了宏任务和微任务
1.同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数
2.当指定的事情完成时,Event Table会将这个函数移入Event Queue。
3.主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
4.上述过程会不断重复,也就是常说的Event Loop(事件循环)。
而定时器是一个宏任务,在运行是会先执行setTimeOut,当主线程任务执行完,setState入场,执行回调函数,在异步方法结束过后,又会执行setTimeOut里面的同步代码。

页面获取节点

类组件获取方法
//方法一:在DOM标签上通过ref属性命名,然后,在挂载后声明周期中用setState方法进行赋值,这样的方法获取到的是一个标签。
componentDidMount() {
        this.setState({
            node: this.refs.node
        },() => {
            console.log(this.state.node)
        })
    }
<button ref='node' onClick={this.subAge.bind(this)}>减少年龄</button>

//方法2:通过createRef()方法来获取。
state = {
     name: 'zhangsan',
     age: 16,
     node: '',
     node1: createRef()  //创建节点的方法
 }
 componentDidMount() {
      this.setState({
          node: this.refs.node
      },() => {
          console.log(this.state.node)
          console.log(this.state.node1) // 获取到的是一个组件对象,拥有许多的方法,可以调用
      })
  }

//ref的数据绑定
 <button ref={this.state.node1} onClick={this.addAge.bind(this)}>增加年龄</button>

在这里插入图片描述

函数组件获取方法
const node = useRef()  //useRef()是一个异步方法
    console.log(node)   //undefine
    useEffect(() => {
        console.log(node) 
    },[node])
//通过使用useRef()来获取DOM节点,与createRef()类似。
<button ref={node} onClick={addAge}>增加年龄</button>

生命周期

有哪些生命周期

组件将要挂载时触发的函数:componentWillMount
组件挂载完成时触发的函数:componentDidMount
是否要更新数据时触发的函数:shouldComponentUpdate
将要更新数据时触发的函数:componentWillUpdate
数据更新完成时触发的函数:componentDidUpdate
组件将要销毁时触发的函数:componentWillUnmount
父组件中改变了props传值时触发的函数:componentWillReceiveProps
在这里插入图片描述

componentWillMount

在渲染前调用
组件还没有渲染完成,DOM还没挂载,组件还没有进入render

componentDidMount

在第一次渲染结束后调用
在这里已经进行了render挂载,组件第一次渲染完成,dom也完成了挂载,在这里我们可以发送ajax,修改state初始值,当调用了setState方法后会重新调用render方法,可以重新渲染,由于setState的这个特性,所以在render中我们不能使用该方法,否者会造成递归死循环。

shouldComponentUpdate

返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。
nextProps是父组件传给子组件的值,nextState是数据更新之后值,这两个值可以在这个函数中获取到。第二步当确认更新数据之后componentWillUpdate将要更新数据,第三步依旧是render,数据发生改变render重新进行了渲染。第四步是componentDidUpdate数据更新完成。

shouldComponentUpdate(nextProps, nextState){
	if(nextProps.content !== this.props.content){
		return true
	}
	else{
		return false
	}
}
componentWillReceiveProps

在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。

componentWillUpdate

更新之前调用

componentDidUpdate

更新之后会被立即调用。首次渲染不会执行此方法。当组件更新后,可以在此处对DOM进行操作,如果使用this.setState()方法,需要加上限制条件,不然会造成死循环

componentWillUnmount

写在之前,通常在这里我们会释放大数据对象、setTimeout。

类组件钩子函数

useEffect()

它与类组件的componentDidMount、shouldComponentUpdate这个生命周期类似,如果传递了第二个参数,在数据进行改变的时候,只有当被监听的数据发生变化才会执行这个方法,否则不会执行.

useEffect( () =>{
	.........
},[props])
useMemo()

它类似于vue的computed的方法,会进行返回一个计算过后的值。,第二个参数为一个数组,里面包含了我们的依赖项,避免性能消耗,需要有一个返回值,return

let total = useMemo(() =>{
	return amount * rate + amount
},[amount])
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值