美文网首页
在 render 中用 bind 形式给组件传递函数属性对性能的

在 render 中用 bind 形式给组件传递函数属性对性能的

作者: 莫帆海氵 | 来源:发表于2021-03-19 00:05 被阅读0次

    Using Function.prototype.bind in render creates a new function each time the component renders, which may have performance implications.

    在 render 中使用 bind 给每次组件重渲染时候都会生成一个新的函数,这会造成不必要的组件更新

    简单的列子

    import React from 'react'
    
    class A1 extends React.PureComponent {
      constructor(props) {
        super(props)
    
        this.state = {
          count: 0
        }
      }
      fly = () => {
        this.setState((state) => {return { count: state.count + 1 } })
      }
      render() {
        console.log('A1 render', this.state.count)
        return (
          <div>
            <h1>A1 count {this.state.count}</h1>
            <B1 text="bird" onFly={this.fly.bind(this)} />
            <B1 text="dog" onFly={this.fly} />
          </div>
        )
      }
    }
    
    class B1 extends React.PureComponent {
      render() {
        const { text, onFly } = this.props
        console.log('B1 render', text)
        return (
          <p>
            <button onClick={onFly}>fly {text}</button>
          </p>
        )
      }
    }
    
    export default A1
    

    执行的结果

    A1 render 1
    B1 render bird
    A1 render 2
    B1 render bird
    A1 render 3
    B1 render bird
    A1 render 4
    B1 render bird
    
    

    通过上面的结果能看出,每次点击都会更新有 bind 函数属性的组件,而不会更新没有 bind 函数属性的组件。

    但并不是所有函数属性都需要 bind 形式,只有在函数属性是传递给其它组件(非原生)时候才需要。比如下面的例子就不需要 bind 形式。

    class A1 extends React.PureComponent {
      constructor(props) {
        super(props)
    
        this.state = {
          count: 0
        }
      }
      fly() {
        this.setState((state) => {return { count: state.count + 1 } })
      }
      render() {
        console.log('A1 render', this.state.count)
        return (
          <div>
            <h1>A1 count {this.state.count}</h1>
            <button onClick={this.fly}>fly c</button>
          </div>
        )
      }
    }
    

    bind 的好处

    bind 形式的函数属性更常见的作用是为了传递参数,这样的写法会很便利

    fly(id) {
        // to do something with id
    }
    
    {list.map(item => {
        return(<button onClick={this.fly.bind(this, item.id)} />)
    })
    
    

    这种如果点击事件在 dom 节点上且只是传递简单的参数(比如 id、名称等),可以使用 dom dataset 传值

    fly(e) {
        let id = e.target.dataset.id
        // to do something with id
    }
    
    {list.map(item => {
        return(<button onClick={this.fly} data-id={item.id} />)
    })
    
    

    如果是自定义的组件,那需要在组件内部处理点击的参数传递

    fly(e) {
        let id = e.target.dataset.id
        // to do something with id
    }
    
    {list.map(item => {
        return(<B1 onFly={this.fly} id={item.id} />)
    })
    
    class B1 extends React.PureComponent {
      render() {
        const { text, onFly, id } = this.props
        console.log('B1 render', text)
        return (
          <p>
            <button onClick={onFly} data-id={id}>fly {text}</button>
          </p>
        )
      }
    }
    

    相关文章

      网友评论

          本文标题:在 render 中用 bind 形式给组件传递函数属性对性能的

          本文链接:https://www.haomeiwen.com/subject/bopmcltx.html