React - 如何将参数传递给事件处理程序

7
好的,所以我对React比较陌生,有一件事情一直让我很困扰:我似乎无法得到一个关于如何传递参数给事件处理程序的明确答案。目前我看到有两种方法:
props.squareClick.bind(this, argument)

onClick={() => props.squareClick(argument)}

我一直在阅读的主要问题是性能成本。因为内联函数或带有Bind的函数在重新渲染时被视为全新的函数,所以会有额外的GC开销,并且对于类组件,它可能会破坏PureComponent中的shouldComponentRender的浅检查。
然后有些人说这是过度优化,我不应该担心它,只需使用内联函数即可。这很酷,但老实说,所有这些相互矛盾的信息让我感到困惑。
因此,我将包含一个代码示例。它来自我制作的一个井字棋应用程序,以练习React。它是一个用于单个方格的功能组件。该组件重复使用于所有方格,并传递一个键作为prop(例如,TOP_LEFT)以指示它是哪个方格。还有一个单击处理程序,当单击Square时,会将事件发送回父组件。为了让单击处理程序知道单击了哪个Square,该键属性被传递为参数。
请查看此代码并给我反馈。这在React中是可接受的做法吗?它会产生性能损失,那么性能损失会很大吗?最后,如果您的答案是我不应该这样做,请清楚地向我解释更好的做法。
import React from 'react';

const Square = props => {
    return (
        <div onClick={() => props.squareClick(props.key)}>
            <p>{props.value}</p>
        </div>
    );
};

export default Square;

如果您有许多这样的正方形组件,它们经常更新,则需要担心性能问题,否则可以使用内联箭头函数。然而最好遵循一种实践,避免使用内联箭头函数,因为随着应用程序的增长,解决此类性能问题将变得困难。请查看以下内容,了解如何避免此类情况 https://dev59.com/BlcO5IYBdhLWcg3w7lrq#45053753 - Shubham Khatri
3个回答

9

我通常使用数据集来完成这个任务:

import React from 'react';

const Square = props => {
    return (
        <div
          data-key={props.key}
          onClick={props.squareClick}>
            <p>{props.value}</p>
        </div>
    );
};

export default Square;

对于方法本身,您只需将值作为e.target.dataset.key返回即可。

或者您也可以将其转换为类组件:

import React from 'react';

class Square extends React.Component {
    handleClick = e => {
      this.props.squareClick(this.props.key)
    }

    render() {
      return (
          <div onClick={this.handleClick}>
              <p>{this.props.value}</p>
          </div>
      );
    }
};

export default Square;

啊,有意思。我不知道目标对象上还有一个数据集属性。我之前用的是数据属性,但是是通过 e.target.getAttribute('data-key') 来获取的。 - Dan Zuzevich
数据集的方法很好。对于这个例子,OP不需要或需要将组件转换为类,因为这里提供了props。但是对于其他情况,数据集可能非常有用。编辑:使用数据集时,OP当然不需要处理函数。其中一个优点就是这个。 - devserkan

1
在使用React和Typescript时,如果想向事件处理程序传递额外的参数,我会像这样做:
import React from 'react';

export default class MyComponent extends React.Component {

    constructor(props: any) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

    render() {
        return (
            <div>
                <p onClick={(this.handleClick("Volvo"))}>Volvo</p>
                <p onClick={this.handleClick("Saab")} >Saab</p>
                <p onClick={this.handleClick("Mercedes")} >Mercedes</p>
                <p onClick={this.handleClick("Audi")} >Audi</p>
                <div id="selectResult">
                </div>
            </div>
        );
    }

    handleClick(selected: string): ((event: React.MouseEvent<HTMLElement, MouseEvent>) => void) {
        return (e) => {
            e.preventDefault();
            document.getElementById("selectResult")!.innerHTML = "You clicked: " + selected;
        }
    }

}

此示例的项目也可在Codpen中查看。


0

针对你的示例,可以使用以下内容:

import React from 'react';

const Square = props => {
    const handleClick = () => props.squareClick(props.key);
    return (
        <div onClick={handleClick}>
            <p>{props.value}</p>
        </div>
    );
};

export default Square;

通过这种方法,仅使用函数的引用,函数本身不会每次都被重新创建。但是,在某些情况下,人们无法使用此类方法并寻求其他解决方案。这里有很多类似以下问题的多个问题:

如何将变量传递给函数引用?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接