zoukankan      html  css  js  c++  java
  • React---新扩展Context和组件优化

    一、Context

    1. 理解
       一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信
    2. 使用
      1) 创建Context容器对象:
          const XxxContext = React.createContext()  
        
      2) 渲染子组时,外面包裹xxxContext.Provider, 通过value属性给后代组件传递数据:
          <xxxContext.Provider value={数据}>
              子组件
          </xxxContext.Provider>
        
      3) 后代组件读取数据:

          //第一种方式:仅适用于类组件 
            static contextType = xxxContext  // 声明接收context
            this.context // 读取context中的value数据
          
          //第二种方式: 函数组件与类组件都可以
            <xxxContext.Consumer>
              {
                value => ( // value就是context中的value数据
                  要显示的内容
                )
              }
            </xxxContext.Consumer>

    3. 注意
        在应用开发中一般不用context, 一般都用它封装react插件
    4. 代码
     1 import React, { Component } from 'react'
     2 import './index.css'
     3 
     4 //创建Context对象
     5 const MyContext = React.createContext()
     6 const {Provider,Consumer} = MyContext
     7 export default class A extends Component {
     8 
     9     state = {username:'tom',age:18}
    10 
    11     render() {
    12         const {username,age} = this.state
    13         return (
    14             <div className="parent">
    15                 <h3>我是A组件</h3>
    16                 <h4>我的用户名是:{username}</h4>
    17                 <Provider value={{username,age}}>
    18                     <B/>
    19                 </Provider>
    20             </div>
    21         )
    22     }
    23 }
    24 
    25 class B extends Component {
    26     render() {
    27         return (
    28             <div className="child">
    29                 <h3>我是B组件</h3>
    30                 <C/>
    31             </div>
    32         )
    33     }
    34 }
    35 
    36 /* class C extends Component {
    37     //声明接收context
    38     static contextType = MyContext
    39     render() {
    40         const {username,age} = this.context
    41         return (
    42             <div className="grand">
    43                 <h3>我是C组件</h3>
    44                 <h4>我从A组件接收到的用户名:{username},年龄是{age}</h4>
    45             </div>
    46         )
    47     }
    48 } */
    49 
    50 function C(){
    51     return (
    52         <div className="grand">
    53             <h3>我是C组件</h3>
    54             <h4>我从A组件接收到的用户名:
    55             <Consumer>
    56                 {value => `${value.username},年龄是${value.age}`}
    57             </Consumer>
    58             </h4>
    59         </div>
    60     )
    61 }

    二、optimize组件优化

    1. Component的2个问题 
         1)只要执行setState(),即使不改变状态数据, 组件也会重新render()
         2) 只当前组件重新render(), 就会自动重新render子组件 ==> 效率低

    2. 效率高的做法
        只有当组件的state或props数据发生改变时才重新render()
    3. 原因
        Component中的shouldComponentUpdate()总是返回true
    4. 解决

          方法1: 
              重写shouldComponentUpdate()方法
              比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
          方法2:  
              使用PureComponent
              PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
              注意: 
                  只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false  
                  不要直接修改state数据, 而是要产生新数据
          项目中一般使用PureComponent来优化

    5. 代码

     1 import React, { PureComponent } from 'react'
     2 import './index.css'
     3 
     4 export default class Parent extends PureComponent {
     5 
     6     state = {carName:"奔驰c36",stus:['小张','小李','小王']}
     7 
     8     addStu = ()=>{
     9         /* const {stus} = this.state
    10         stus.unshift('小刘')
    11         this.setState({stus}) */
    12 
    13         const {stus} = this.state
    14         this.setState({stus:['小刘',...stus]})
    15     }
    16 
    17     changeCar = ()=>{
    18         //this.setState({carName:'迈巴赫'})
    19 
    20         const obj = this.state
    21         obj.carName = '迈巴赫'
    22         console.log(obj === this.state);
    23         this.setState(obj)
    24     }
    25 
    26     /* shouldComponentUpdate(nextProps,nextState){
    27         // console.log(this.props,this.state); //目前的props和state
    28         // console.log(nextProps,nextState); //接下要变化的目标props,目标state
    29         return !this.state.carName === nextState.carName
    30     } */
    31 
    32     render() {
    33         console.log('Parent---render');
    34         const {carName} = this.state
    35         return (
    36             <div className="parent">
    37                 <h3>我是Parent组件</h3>
    38                 {this.state.stus}&nbsp;
    39                 <span>我的车名字是:{carName}</span><br/>
    40                 <button onClick={this.changeCar}>点我换车</button>
    41                 <button onClick={this.addStu}>添加一个小刘</button>
    42                 <Child carName="奥拓"/>
    43             </div>
    44         )
    45     }
    46 }
    47 
    48 class Child extends PureComponent {
    49 
    50     /* shouldComponentUpdate(nextProps,nextState){
    51         console.log(this.props,this.state); //目前的props和state
    52         console.log(nextProps,nextState); //接下要变化的目标props,目标state
    53         return !this.props.carName === nextProps.carName
    54     } */
    55 
    56     render() {
    57         console.log('Child---render');
    58         return (
    59             <div className="child">
    60                 <h3>我是Child组件</h3>
    61                 <span>我接到的车是:{this.props.carName}</span>
    62             </div>
    63         )
    64     }
    65 }
  • 相关阅读:
    【Solr】copy字段的应用
    【Solr】Solr的安装部署
    【UEditor】 UEditor整合项目上传资源到阿里云服务器
    【Bootstrap】Bootstrap和Java分页-第二篇
    【Bootstrap】Bootstrap和Java分页-第一篇
    工作那点小事
    ubuntu安装mongodb
    mybatis插入返回主键
    linux查看端口占用命令
    ubuntu安装ssh
  • 原文地址:https://www.cnblogs.com/le220/p/14736734.html
Copyright © 2011-2022 走看看