• context和optimize优化


    3. context和optimize优化

    3.1 context

    context用于祖孙组件之间的传参

    import React, {Component} from 'react';
    import './index.css'
    
    // 创建一个context组件,供传递数据使用
    const MyContext = React.createContext()
    
    class A extends Component {
    
        state = {username: 'cxk', age:18}
    
        render() {
            const {username} = this.state
            return (
                <div className='parent'>
                    <h3>我是A组件</h3>
                    <h4>我的用户名是:{username}</h4>
    
                    {/* 固定写法*/}
                    <MyContext.Provider value={this.state}>
                        <B/>
                    </MyContext.Provider>
                </div>
            );
        }
    }
    
    //第一种方式:仅适用于类组件
    class B extends Component {
        // 声明使用contex,才能获取到祖组件传递的数据
        static contextType = MyContext
    
        render() {
            // 读取context中的value数据
            // console.log(this.context)
            return (
                <div className='child'>
                    <h3>我是B组件</h3>
                    <h4>我从A接收到的用户名是:{this.context.username}</h4>
                    <C/>
                </div>
            );
        }
    }
    
    // class C extends Component {
    //     // 声明使用contex,才能获取到祖组件传递的数据
    //     static contextType = MyContext
    //
    //     render() {
    //         // console.log(this)
    //         return (
    //             <div className='grand'>
    //                 <h3>我是C组件</h3>
    //                 <h4>我从A收到的用户名是:{this.context.username}, 年龄是{this.context.age}</h4>
    //             </div>
    //         );
    //     }
    // }
    
    //第二种方式: 函数组件与类组件都可以
    function C() {
        return (
                <div className='grand'>
                    <h3>我是C组件</h3>
                    <h4>我从A收到的用户名是:
                         {/*函数式组件使用context取值, 类式组件也可以*/}
                         <MyContext.Consumer>
                             {
                                 (value)=>{ 	// value就是context中的value数据
                                     return `${value.username} 年龄是:${value.age}`
                                 }
                             }
                         </MyContext.Consumer>
                    </h4>
                </div>
            );
    }
    
    
    export default A;
    

    注意

    在应用开发中一般不用context, 一般都用它的封装react插件
    

    3.2 optimize优化

    Component的2个问题

    1. 只要执行setState(),即使不改变状态数据, 组件也会重新render() ==> 效率低

    2. 只当前组件重新render(), 就会自动重新render子组件,纵使子组件没有用到父组件的任何数据 ==> 效率低

    效率高的做法

    只有当组件的state或props数据发生改变时才重新render()

    原因

    Component中的shouldComponentUpdate()总是返回true

    解决

    办法1: 
    	重写shouldComponentUpdate()方法
    	比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
    办法2:  
    	使用PureComponent
    	PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
    	注意: 
    		只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false  
    		不要直接修改state数据, 而是要产生新数据
    项目中一般使用PureComponent来优化
    
    import React, {Component, PureComponent} from 'react';
    import './index.css'
    
    class Parent extends PureComponent {
    
        state = {carName: 'BMW', stus:['a','b','c']}
    
        addStu = () => {
            // 错误
    /*        const {stus} = this.state
            stus.unshift('老王')
            this.setState({stus})*/
    
            // 正确
            const {stus} = this.state
            this.setState({stus:['老王',...stus]})
    
        }
    
        changeCar = () => {
            // this.setState({})
    
            // 使用PureComponent后不能在原来得对象修改,不然就视为没有更新 ,所以点击并没有触发render,
            // const obj = this.state
            // obj.carName = 'AMG'
            // this.setState(obj)
    
            // 正确
            this.setState({carName: 'AMG'})
    
        }
    
        // shouldComponentUpdate(nextProps, nextState, nextContext) {
        //     console.log(nextProps,nextState)
        //     console.log(this.props,this.state)
        //     return !(nextState.carName === this.state.carName)
        // }
    
        render() {
            console.log('parent---render')
            const {carName} = this.state
            return (
                <div className='parent'>
                    <h3>我是Parent组件</h3>
                    <span>{this.state.stus}&nbsp</span>
                    <span>我的车现在是{carName}</span>
                    <button onClick={this.changeCar}>点我换车</button>
                    <button onClick={this.addStu}>添加一个老王</button>
                    <Child carName={carName}/>
                </div>
            );
        }
    }
    class Child extends PureComponent {
    
        // shouldComponentUpdate(nextProps, nextState, nextContext) {
        //     // console.log(nextProps,nextState)
        //     // console.log(this.props,this.state)
        //     return !(nextProps.carName === this.props.carName)
        // }
    
        render() {
            // 使用PureComponent后若子组件的数据没更新就不会触发render
            console.log('child---render')
            return (
                <div className='child'>
                    <h3>我是Child组件</h3>
                    <span>我接到的车是{this.props.carName}</span>
                </div>
            );
        }
    }
    
    export default Parent;
    
  • 相关阅读:
    Service与Activity通信 回调方式***
    WeakReference 在android中的应用
    解决用官方容器启动redmine无法插入中文字符的问题
    Python 使用scapy 时报:ImportError: cannot import name 'NPCAP_PATH' 解决
    python3 图片文字识别
    python3 读取dbf文件报错 UnicodeDecodeError: 'gbk' codec can't decode
    RbbitMQ消息队列及python实现
    windows10创建ftp服务器
    什么是ip代理
    Python3爬虫实例 代理的使用
  • 原文地址:https://www.cnblogs.com/guapitomjoy/p/15223809.html
Copyright © 2020-2023  润新知