zoukankan      html  css  js  c++  java
  • react中这些细节你注意过没有?

    react中的一些细节知识点:

    1、组件中get的使用(作为类的getter)

    ES6知识:class类也有自己的getter和setter,写法如下:

    Class Component {
         constructor() {
             super()
             this.name = ''
        }    
        
        // name的getter
        get name() {
            ...
        }
    
        // name的setter
        set name(value) {
            ...
       }
    }

    react组件中的get的使用如下:

    /*
     *  renderFullName的getter 
     *  可以直接在render中使用this.renderFullName
     */ 
    
    get renderFullName () {
      return `${this.props.firstName} ${this.props.lastName}`;
    }
    
    render() {
        return (
              <div>{this.renderFullName}</div>
        )   
    }

    那getter在react组件中有什么用处呢??

    constructor (props) {
        super()
        this.state = {};
      }
    
        
      render () {
        // 常规写法,在render中直接计算 
        var fullName = `${this.props.firstName} ${this.props.lastName}`;
    
        return (
          <div>
            <h2>{fullName}</h2>
          </div>
        );
      }
    // 较为优雅的写法:,减少render函数的臃肿
    renderFullName () {
      return `${this.props.firstName} ${this.props.lastName}`;
    }
    
    render () {
      var fullName = this.renderFullName() 
      <div>{
    fullName }</div>
    }
    // 推荐的做法:通过getter而不是函数形式,减少变量
    get renderFullName () {
      return `${this.props.firstName} ${this.props.lastName}`;
    }
    
    render () {
       <div>{ this.renderFullName  }</div> 
    }

    如果你了解Vue的话,那么你知道其中的 computed: {}  计算属性,它的底层也是使用了getter,只不过是对象的getter不是类的getter

    // 计算属性,计算renderFullName
    computed: {
        renderFullName: () => {
             return `${this.firstName} ${this.lastName}`;
        }
    }

    Vue的computed有一个优势就是:

    计算属性对比函数执行:会有缓存,减少计算 --->   计算属性只有在它的相关依赖发生改变时才会重新求值

    这就意味着只要 firstName和lastName还没有发生改变,多次访问renderFullName计算属性会立即返回之前的计算结果,而不必再次执行函数。

    那么是否react的getter也有缓存这个优势吗???   答案是:没有,react中的getter并没有做缓存优化

    2、组件的attr及事件执行顺序:

      A、父子组件:以props形式,父传递给子

      B、同一组件:后面覆盖前面。

    依靠上述规则,那么要使得 attr 的权重最高,应该放到最底层的组件中,而且位置尽量的靠后。

    <-- 父组件Parent | 调用子组件并传递onChange属性 -->
    <div>
        <Child  onChange={this.handleParentChange} />
    </div>
    
    <-- 子组件Child | 接收父组件onChange, 自己也有onChange属性 -->
    <input {...this.props} onChange={this.handleChildChange}  />

    此时,Child组件执行的onChange只是执行handleChildChange事件,handleParentChange事件并不会执行.

    • 1.如果只需要执行handleParentChange怎么办??   input中  {...this.props} 与 onChange={this.handleChildChange} 换个位置
    • 2.如果两个事件都需要执行怎么办??                      在Child组件中  handleChildChange 中执行 this.props.handleParentChange

    3、类中的方法用ES6形式简写的不同之处:  fn = () => {}   与   fn() {}   的区别:

    export default Class Child extends Component {
        constructor (props) {
            super()
            this.state = {};
       }
    
        // 写法1,这是ES6的类的方法写法
        fn1() {
             console.log(this)
            // 输出 undefined
        }
     
        // 写法2,这是react的方法写法
        fn2 = () => {
             console.log(this)
             // 输出:Child {props: {…}, context: {…}, refs: {…}, …}
        }
    
       render () {
            return (
              <div>
                   <button onClick={this.fn1}>fn1方法执行</button >
                   <button onClick={this.fn2}>fn2方法执行</button >
              </div>
             );
       }
    }    

    可见两种写法,函数内的this指向时不同的。

    那它们就没有相同之处吗??,  以下三种情况是相同的:

    情况1:函数内部用不到this的时候,两者相等。

        // 写法1,这是ES6的类的方法写法
        fn1() {
            return 1 + 1
        }
     
        // 写法2,这是react的方法写法
        fn2 = () => {
             return 1 + 1
        }

    情况2:两者在render中直接执行的时候。

        // 写法1,这是ES6的类的方法写法
        fn1() {
             console.log(this)
            // Child {props: {…}, context: {…}, refs: {…}, …}
        }
     
        // 写法2,这是react的方法写法
        fn2 = () => {
             console.log(this)
             // 输出:Child {props: {…}, context: {…}, refs: {…}, …}
        }
    
       render () {
            return (
              <div>
                   <button onClick={() => {
                            this.fn1();
                    }}>fn1方法执行</button >
    
                   <button onClick={() => {
                            this.fn2();
                    }}>fn2方法执行</button >
              </div>
             );
       }    

    情况3:给this.fn2.bind(this),绑定this作用上下文。 

    // 写法1,这是ES6的类的方法写法
        fn1() {
             console.log(this)
            // Child {props: {…}, context: {…}, refs: {…}, …}
        }
     
        // 写法2,这是react的方法写法
        fn2 = () => {
             console.log(this)
             // 输出:Child {props: {…}, context: {…}, refs: {…}, …}
        }
    
       render () {
            return (
              <div>
                   <button onClick={this.fn1}>fn1方法执行</button >
    
                   <button onClick={this.fn2.bind(this)}>fn2方法执行</button >
              </div>
             );
       }    

    注意,不要和ES6中对象的方法简写弄混了,以下是对象Obeject的方法简写:

    阮一峰ES6: http://es6.ruanyifeng.com/#docs/object

    4、列表渲染中的数组。

    参考:https://doc.react-china.org/docs/lists-and-keys.html

    正常的jsx写法是在render中写类似于HTML的语法,标签嵌套标签<div><input /></div>,有js,用 { 花括号 }。

    但是不知道你注意过没有,数组可以嵌套在标签内部,正常渲染。

    function NumberList(props) {
        const numbers = [1,2,3,4,5];
    
        // listItems是数组numbers通过map返回的,本质也是个数组。 
        const listItems = numbers.map((number) =>
            <li>{number}</li>
        );
    
        return (
            <ul>
                 // 可以替换成 [ <li>1</li>,  <li>2</li>,  .....]
                 {listItems}
            </ul>
        );
    }    

    如上所示,标签内部的数组是可以正确渲染的,那么就有以下的写法:

    renderItem(name) {
        const A = <li key={'a'}>A</li>, 
                 B = <li key={'b'}>B</li>, 
                 C = <li key={'c'}>C</li>, 
                 D = <li key={'d'}>D</li>;
         let operationList;
    
         switch (name) {
            case 1:
                operationList = [A , B,  C]
               break;
            case 2:
                operationList = [B,  C, D]
                break;
            case 0:
               operationList = [A]
               break;
        }
        return operationList;
    }
    
    render() {
       // this.renderItem() 执行结果是数组
        return (
             <ul>{  this.renderItem() }</ul>
        )
    }        

  • 相关阅读:
    一文读懂快速排序
    15道APP测试面试题分享,助攻你的面试
    APP测试之使用ADB可能遇到的错误及解决办法
    APP测试之Monkey压力测试(二)
    APP测试之Monkey压力测试(一)
    APP日志文件抓取及分析
    Linux环境安装python3
    visualvm 插件 visual gc 使用介绍
    设计模式之状态
    【深入理解JVM】:Java内存模型JMM
  • 原文地址:https://www.cnblogs.com/faith3/p/9219448.html
Copyright © 2011-2022 走看看