IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React学习分享(五) -> 正文阅读

[JavaScript知识库]React学习分享(五)

十三、React生命周期函数

1.初始化阶段
(1)componentWillMount:render之前最后一次修改状态。注意:在react18之后被弃用了,如果想render之前最后一次修改状态只能在constructor里面进行修改
类似于vue的beforeMount,在这个阶段之前是constructor,但是constructor不属于生命周期函数。
(2)render:只能访问this.props和this.state,不允许修改状态和DOM
(3)componentDidMount:成功render并渲染完成真实DOM之后,可以修改DOM。可以进行数据请求axios、订阅函数调用、setInterval定时器、基于创建的完的dom进行 初始化第三方组件(初始化只执行一次)

import React, { Component } from 'react'
export default class APP extends Component {
    state = {
        value: "123"
    }
    constructor() {
        super()
        console.log("constructor");
        this.setState({
            value: "zxc"
        })
    }
    UNSAFE_componentWillMount() {  //不安全的用于去掉黄色警告
        console.log("componentWillMount", this.state.value);
        this.setState({
            value: "asf"
        })
    }
    componentDidMount() {
        console.log("componentDidMount", this.state.value);
        // 数据请求axios
        // 订阅函数调用
        // setInterval
        // 基于创建的完的dom进行 初始化第三方组件
    }
    render() {
        console.log("render", this.state.value);
        return (
            <div>APP</div>
        )
    }
}

2.运行中阶段(更新阶段)
(1)shouldComponentUpdate:返回false会阻止render再次调用渲染页面。例如:我们点击按钮调用setState对状态进行修改,我们修改完之后,继续点击,会发现componentDidUpdate函数会一直打印出此DOM节点,页面一直重复渲染相同的内容,调用diff算法,所以防止这样,我们可以判断新的state状态和老的state状态是否一样。
(2)componentWillUpdate:render更新前,不能修改属性和状态,获取不到DOM
(3)componentDidUpdate:可以修改DOM

import axios from 'axios'
import React, { Component } from 'react'
export default class App extends Component {
    state = {
        name: "xiaozhang",
        list: []
    }
    componentDidMount() {
        axios.get("/test.json").then((res) => {
            this.setState({
                list: res.data.data.films
            })
        })
    }
    render() {
        return (
            <div>
                <button onClick={() => {
                    this.setState({
                        name: "lihua"
                    })
                }}>click</button>
                <span id="name">{this.state.name}</span>
                <div id="warpper" style={{
                    height: "100px", overflow: "hidden", background: "yellow"
                }}>
                    <ul>
                        {
                            this.state.list.map(item =>
                                <li key={item.filmId}>{item.name}</li>
                            )
                        }
                    </ul>
                </div>
            </div>
        )
    }
    shouldComponentUpdate(nextProps, nextState) {
        // return true;   //应该更新
        // return false;; //阻止更新
        
        // this.state   老的状态
        // this.props  老的属性
        // nextState   新的状态
        // nextProps   新的属性
        
        // 这里我们不直接去对比两个对象是否相同,所以先转成字符串进行比较
        if (JSON.stringify(this.state) !== JSON.stringify(nextState)) {
            return true
        }
        return false
    }
    UNSAFE_componentWillMount() {
        console.log("componentWillUpdate", document.getElementById("name"))
    }
    componentDidUpdate(prevProps, prevState) {
        // prevProps  老的属性
        // prevState  老的状态
        // this.props 新的属性
        // this.state 新的状态
        console.log("componentDidUpdate", document.getElementById("name").innerHTML)
        // 更新后, 想要获取dom节点, 更新
        console.log(prevState.list)
        if (prevState.list.length === 0) {
            // new BetterScroll("#warpper")
            console.log("warpper");
        }
    }
}

案例:

import React, { Component } from 'react'
class Box extends Component {
    // 在子组件中使用比较多,对性能的优化函数,减少无效的diff算法创建虚拟DOM
    shouldComponentUpdate(nextProps) {
        // 老的属性进行取消,新的属性添加,所以这里会触发两次render
        if (this.props.current === this.props.index || nextProps.current === nextProps.index) {
            return true
        }
        return false
    }
    render() {
        console.log("render")
        return <div style={{ width: "100px", height: "100px", border: this.props.current === this.props.index ? '1px solid red' : '1px solid gray', margin: "10px", float: 'left' }}>
        </div>
    }
}
export default class App extends Component {
    state = {
        list: ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09"],
        current: 0
    }
    render() {
        return (
            <div>
                <input type="number" onChange={(evt) => {
                    console.log(evt.target.value)
                    this.setState({
                        current: Number(evt.target.value)
                    })
                }} value={this.state.current} />
                <div style={{ overflow: "hidden" }}>
                    {
                        this.state.list.map((item, index) =>
                            <Box key={item} current={this.state.current} index={index} />
                        )
                    }
                </div>
            </div>
        )
    }
}

(4)componentWillReceiveProps:父组件修改属性触发,最先获得父组件传来的属性, 可以利用属性进行ajax或者逻辑处理。

import React, { Component } from 'react'
class Child extends Component {
    state = {
        title: ""
    }
    render() {
        return <div>child-{this.state.title}</div>
    }
    componentWillReceiveProps(nextProps) {
        console.log("componentWillReceiveProps", nextProps)
        // 最先获得父组件传来的属性, 可以利用属性进行ajax或者逻辑处理。
        // 把属性转化成孩子自己的状态。
        this.setState({
            title: nextProps.text + "kerwin"
        })
    }
}
export default class App extends Component {
    state = {
        text: "11111111111"
    }
    render() {
        return (
            <div>
                {
                    this.state.text
                }
                <button onClick={() => {
                    this.setState({
                        text: "222222222222"
                    })
                }}>click</button>
                <Child text={this.state.text} />
            </div>
        )
    }
}
  1. 销毁阶段
    (1)componentWillUnmount:在删除组件之前进行清理操作。比如定时器销毁和事件监听器解绑
import React, { Component } from 'react'
export default class App extends Component {
    state = {
        isCreated:true
    }
    render() {
        return (
            <div>
                <button onClick={()=>{
                    this.setState({
                        isCreated:!this.state.isCreated
                    })
                }}>click</button>
                {/* {this.state.isCreated?<Child/>:""} */}
                {this.state.isCreated && <Child/>}
            </div>
        )
    }
}
class Child extends Component{
   
    render(){
        return <div>
            child
        </div>
    }
    componentDidMount() {
    // 事件监听器
        window.onresize = ()=>{
            console.log("resize")
        }
        // 定时器
        this.timer = setInterval(()=>{
            console.log("111")
        },1000)
    }
   
    componentWillUnmount(){
        console.log("componentWillUnmount")
        window.onresize = null
        clearInterval(this.timer)
    }
}

老生命周期的问题:

(1) componentWillMount ,在ssr中这个方法将会被多次调用, 所以会重复触发多遍,同时在这里如果绑定事件, 将无法解绑,导致内存泄漏,变得不够安全高效逐步废弃。
(2) componentWillReceiveProps 外部组件多次频繁更新传入多次不同的 props,会导致不必要的异步请求
(3) componetWillupdate, 更新前记录 DOM 状态, 可能会做一些处理,与componentDidUpdate相隔时间如果过 长, 会导致 状态不太信

新生命周期

  1. getDerivedStateFromProps

getDerivedStateFromProps 本来(React v16.3中)是只在创建和更新(由父组件引发部分),也就是不是不由父组件引发,那么getDerivedStateFromProps也不会被调用,如自身setState引发或者forceUpdate引发
这样的话理解起来有点乱,在React v16.4中改正了这一点,让getDerivedStateFromProps无论是Mounting还是Updating,也无论是因为什么引起的Updating,全部都会被调用。
getDerivedStateFromProps(props, state) 在组件创建时和更新时的render方法之前调用,它应该返回一个对象来更新状态,或者返回null来不更新任何内容

  1. getSnapshotBeforeUpdate

getSnapshotBeforeUpdate() 被调用于render之后,可以读取但无法使用DOM的时候。它使您的组件可以在可能更改之前从DOM捕获一些信息(例如滚动位置)。

react中性能优化的方案

  1. shouldComponentUpdate

控制组件自身或者子组件是否需要更新,尤其在子组件非常多的情况下, 需要进行优化

  1. PureComponent

PureComponent会帮你 比较新props 跟 旧的props, 新的state和老的state(值相等,或者 对象含有相同的属性、且属性值相等 ),决定shouldcomponentUpdate 返回true 或者 false, 从而决定要不要呼叫 render function。 注意: 如果你的 state 或 props 『永远都会变』,那 PureComponent 并不会比较快,因为 shallowEqual 也需要花时间。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:02:48  更:2022-09-04 01:02:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 11:11:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码