通过具有功能组件的道具,而无需在组件内声明功能

时间:2018-12-04 16:35:40

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

我遍历项目列表,并想调用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本身中声明一个函数。

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

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

注意II: 话虽如此,如果您确定这是一个相关的问题并且由于钩子而无法解决,我显然想知道:)

3 个答案:

答案 0 :(得分:1)

  

对于功能组件也是如此吗?

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

  

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

您可以.bind(...)

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

但实际上,您是否注意到重新提交有任何延迟?可能不是,如果不是,那不是由函数声明引起的。编写看起来很美的代码,不要为编译器进行优化,而让编译器来做。

  

但是不久前,我了解到您应该避免在组件JSX本身中声明一个函数

您不应该真正避免使用它,而是尽可能使用其他方法。在这种情况下,确实没有更好的方法。

答案 1 :(得分:0)

您可以声明另一个这样的方法。不要忘记使用.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>
        )
    }
}

答案 2 :(得分:0)

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

然后在子组件内部,您可以轻松地将处理程序引用为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>
        )
    }
}