首页 > 解决方案 > 如何调用具有不同值的函数而不在每次渲染时重新创建新的箭头函数?

问题描述

很明显,我们都知道在render类组件的方法中使用箭头函数并不好,因为它会在每次渲染时创建新函数。

例如

render() { 
    return (
        <div onClick={() => console.log('this is bad')}>I'm dangerous</div>
    )
}

但就我而言,我要做的是拥有一个函数 ( foo),它接收一个参数并使用该参数设置状态。而且我有多个元素,每个元素都有不同的调用值foo

例如

foo = value => this.setState({value})

render() {
    return (
        <div>
            <div onClick={() => this.foo(1)}>1</div> //  this is also bad
            <div onClick={() => this.foo(2)}>2</div> //  this is also bad
            <div onClick={() => this.foo(3)}>3</div> //  this is also bad
            <div onClick={() => this.foo(4)}>4</div> //  this is also bad
            <div onClick={() => this.foo(5)}>5</div> //  this is also bad
        </div>
    )
}

所以我需要一个解决方法,我需要调用相同的函数,只传递不同的参数。

我试图想出的是

  1. 创建一个返回函数的函数

    foo = value => () => this.setState({value})
    
    render() {
        return (
            <div>
                <div onClick={this.foo(1)}>1</div> 
                <div onClick={this.foo(2)}>2</div> 
                <div onClick={this.foo(3)}>3</div> 
                <div onClick={this.foo(4)}>4</div> 
                <div onClick={this.foo(5)}>5</div> 
            </div>
        )
    }
    

    但我认为这和第一个例子一样糟糕

  2. 为每个值创建函数

    foo1 = value => this.setState({value})
    foo2 = value => this.setState({value})
    foo3 = value => this.setState({value})
    foo4 = value => this.setState({value})
    foo5 = value => this.setState({value})
    
    render() {
        return (
            <div>
                <div onClick={this.foo1}>1</div>
                <div onClick={this.foo2}>2</div>
                <div onClick={this.foo2}>3</div>
                <div onClick={this.foo4}>4</div>
                <div onClick={this.foo5}>5</div>
            </div>
        )
    }
    

在每次渲染时都创建一个新函数的情况下,这还不错,但是这样一来,我的组件就会变得巨大而且非常糟糕。

在这种情况下,如何在不为每个渲染创建新函数且不为每个元素值创建一个函数的情况下制作此函数或渲染?

请记住,在我的例子中,真正的值不是数字(1234),元素onClick不是一个简单的div元素,foo不仅调用this.setState,而且还做其他事情。这只是一个例子。

标签: javascriptreactjsarrow-functions

解决方案


在基于类的组件中解决此问题的方法是在创建类本身时绑定函数。

class C {
  foo = () => {
    this.setState({...})
  }

  render() {
    return <div onClick={this.foo} />
  }
}

这将确保该类的每个实例只有一个该函数的实例。如果您已经证明在每个渲染调用中创建函数存在性能问题,我只会建议您这样做。


推荐阅读