简体   繁体   English

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

[英]pass props with functional component without declaring function within component

I iterate over a list of items and want to call a function onClick(). 我遍历项目列表,并想调用onClick()函数。 Example below: 下面的例子:

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>
        )
    }
}

As you can see, I declare a function in the JSX. 如您所见,我在JSX中声明了一个函数。 I do this over and over, but some time ago I learned that you should avoid declaring a function within the component JSX itself, for performance reasons. 我一遍又一遍地执行此操作,但是不久前,我了解到出于性能原因,您应该避免在组件JSX本身中声明一个函数。

Is this true, also for functional components? 功能部件也是如此吗? And if so, is there any other way to pass dynamic information (item, in this case) to a callback? 如果是这样,还有其他方法可以将动态信息(在本例中为项目)传递给回调吗?

NOTE: I'm looking forward to using hooks at some point, but right now I just want to know a best practice without using them. 注意:我期待在某个时候使用钩子,但是现在我只想知道一种最佳实践而不使用它们。

NOTE II: That being said, if you are sure that this is a relevant problem and it could not be solved until now because of hooks, I obviously would like to learn that :) 注意二:话虽如此,如果您确定这是一个相关问题,并且由于钩子而无法解决,那我显然想了解一下:)

Is this true, also for functional components? 功能部件也是如此吗?

Well actually there is no functional component used in your code. 好吧,实际上您的代码中没有使用任何功能组件。 And everything you do in a function that gets called very often ( render() for example) causes performance to decrease, no matter wether that is a function or variable declaration or invokation. 无论是函数,变量声明还是调用,在经常调用的函数render()例如render()所做的所有操作都会导致性能下降。 Wether that decrease matters is another thing. 减少问题是另一回事。

And if so, is there any other way to pass dynamic information (item, in this case) to a callback? 如果是这样,还有其他方法可以将动态信息(在本例中为项目)传递给回调吗?

You could .bind(...) it: 你可以.bind(...)它:

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

but really, did you notice any delay on a rerender? 但实际上,您是否注意到重新提交有任何延迟? Probably not, and if so that is not caused by the function declaration. 可能不是,如果不是,那不是由函数声明引起的。 Write code that looks beautiful to you, don't optimize for the compiler, let the compiler do that. 写出看起来很美的代码,不要为编译器进行优化,而让编译器来做。

but some time ago I learned that you should avoid declaring a function within the component JSX itself 但是前段时间我了解到您应该避免在组件JSX本身中声明一个函数

You shouldn't really avoid it, rather prefer other ways if possible. 您不应该真正避免使用它,而是尽可能使用其他方法。 In this case there is not really a better way so go with it. 在这种情况下,并没有更好的方法。

You can declare another method like this. 您可以声明另一个这样的方法。 Don't forget to use .bind . 不要忘记使用.bind Otherwise, the method won't be called correctly. 否则,该方法将无法正确调用。

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>
        )
    }
}

You can create a parent component which will be responsible for looping through the items and passing the click handler down as a prop to each individual child component. 您可以创建一个父组件,该父组件将负责遍历所有项目,并将点击处理程序作为道具传递给每个子组件。

Then inside the child component you can easily reference the handler as this.props.onClick 然后,在子组件内部,您可以轻松地将处理程序引用为this.props.onClick

Functions (objects) are passed by reference in JavaScript. 函数(对象)在JavaScript中通过引用传递。 By declaring it in the parent scope it will only take up space there. 通过在父作用域中声明它,只会在那儿占用空间。 If initialized in the child, it will create space in memory for the function with each child component. 如果在子级中初始化,它将为每个子级组件的函数在内存中创建空间。

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>
        )
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM