【问题标题】:pass props with functional component without declaring function within component使用功能组件传递道具而不在组件内声明功能
【发布时间】:2018-12-04 16:35:40
【问题描述】:

我遍历一个项目列表并想调用一个函数 onClick()。下面的例子:

class App extends Component {
    state = { items: [1, 2, 3, 4] };

    click = i => console.log(i);

    render() {
        return (
            <div>
                {this.state.items.map(item => (
                    <div 
                        key={item} 
                        // this works fine, but I rather not declare functions within the render function / JSX
                        onClick={() => this.click(item)}
                    >
                        {`click on # ${item}`}
                    </div>
                ))}
            </div>
        )
    }
}

如您所见,我在 JSX 中声明了一个函数。我一遍又一遍地这样做,但前段时间我了解到,出于性能原因,您应该避免在组件 JSX 本身中声明函数。

对于功能组件也是如此吗?如果是这样,还有其他方法可以将动态信息(在本例中为项目)传递给回调吗?

注意: 我期待在某个时候使用钩子,但现在我只想知道不使用它们的最佳实践。

注意二: 话虽这么说,如果您确定这是一个相关问题并且由于钩子直到现在无法解决,我显然想知道:)

【问题讨论】:

  • 是的,钩子是最好的选择。但是你可以做一个函数引用而不是定义函数。类似onClick={this.handleClick}

标签: javascript reactjs callback arrow-functions react-props


【解决方案1】:

这是真的吗,也适用于功能组件?

实际上,您的代码中没有使用任何功能组件。你在一个经常被调用的函数(例如render())中所做的一切都会导致性能下降,无论是函数还是变量声明或调用。减少是否重要是另一回事。

如果是这样,有没有其他方法可以将动态信息(在本例中为项目)传递给回调?

你可以.bind(...)它:

 onClick = {console.log.bind(console, item) }

但实际上,您是否注意到重新渲染有任何延迟?可能不是,如果是这样,那不是由函数声明引起的。编写对你来说看起来很漂亮的代码,不要为编译器优化,让编译器来做。

但前段时间我了解到你应该避免在组件 JSX 本身中声明函数

您不应该真的避免它,而是尽可能选择其他方式。在这种情况下,真的没有更好的方法,所以就去吧。

【讨论】:

  • 谢谢!我的代码中没有功能组件,没错,但我简化了此代码,而在现实生活中,我可能会将内部 div 重构为功能组件。但是,最重要的是,您确认这种方式是可以的,只要您实际上并没有感觉到疼痛,无论是在性能方面还是在其他方面。对我有很大帮助,谢谢!
【解决方案2】:

您可以像这样声明另一个方法。不要忘记使用.bind。否则,该方法将无法正确调用。

class App extends Component {
    state = { items: [1, 2, 3, 4] };

    handleClick(item) {
        // do something
        console.log(item);
    }
    render() {
        return (
            <div>
                {this.state.items.map(item => (
                    <div 
                        key={item} 
                        // this works fine, but I rather not declare functions within the render function / JSX
                        onClick={this.handleClick.bind(this, item)}
                    >
                        {`click on # ${item}`}
                    </div>
                ))}
            </div>
        )
    }
}

【讨论】:

    【解决方案3】:

    您可以创建一个父组件,该组件将负责遍历项目并将点击处理程序作为道具向下传递给每个单独的子组件。

    然后在子组件中,您可以轻松地将处理程序引用为this.props.onClick

    函数(对象)在 JavaScript 中通过引用传递。通过在父范围内声明它只会占用那里的空间。如果在子组件中初始化,它将在内存中为每个子组件的函数创建空间。

    class Parent extends Component {
        state = { items: [1, 2, 3, 4] };
    
        parentClick(item) {
            // do something
            console.log(item);
        }
        render() {
            return (
                <div>
                    {this.state.items.map(item => (
                      <Child item={item} onClick={this.parentClick}>
                    ))}
                </div>
            )
        }
    }
    
    
    
    class Child extends Component {
    
        childClick(item) {
            this.props.onClick(item)
        }
    
        render() {
            return (
                <div>
                    <p onClick={this.childClick(this.props.item)}>this.props.item</p>
                </div>
            )
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-19
      • 2020-08-20
      • 2020-08-19
      • 2021-02-02
      • 2019-12-05
      • 2022-01-23
      • 1970-01-01
      • 2020-09-11
      相关资源
      最近更新 更多