【问题标题】:React - How to Pass an Argument to an Event HandlerReact - 如何将参数传递给事件处理程序
【发布时间】:2018-12-05 03:29:11
【问题描述】:

好的,所以我是 React 的新手,关于事件处理程序的一件事真的非常困扰我:我似乎无法得到关于如何将参数传递给它们的直接答案。到目前为止,我见过两种方式:

绑定
props.squareClick.bind(this, argument)
排队
onClick={() => props.squareClick(argument)}

我一直在阅读的重要内容是性能成本。因为内联函数或带有 Bind 的函数在重新渲染时会被视为全新的函数,所以会产生额外的 GC 开销,而且对于类组件,它可能会中断对带有 PureComponent 的 shouldComponentRender 的浅层检查。

然后有人说这是过度优化,我不应该担心它,只需使用内联函数即可。这很酷,但老实说,所有这些相互矛盾的信息都让我感到困惑。

所以,我将包含一个代码示例。它取自我为练习 React 而制作的井字游戏应用程序。它是板上单个 Square 的功能组件。这个组件被所有的方格重复使用,并且一个键作为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;

【问题讨论】:

  • 如果你有很多这样的方形组件并且经常更新,那么你需要担心性能影响,否则你可以使用内联箭头功能。但是,最好将其作为一种避免使用内联箭头函数的做法,因为随着应用程序的增长,解决此类性能问题将变得困难。检查一下如何避免这种情况stackoverflow.com/questions/45053622/…

标签: javascript reactjs


【解决方案1】:

我通常做的是使用datasets:

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')
  • 数据集的好方法。对于此示例,OP 不需要它或需要将组件转换为类,因为此处提供了道具。但对于其他情况,数据集可能非常有用。编辑:使用数据集 OP 当然不需要句柄功能。一个优点是。
【解决方案2】:

在 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

【讨论】:

    【解决方案3】:

    对于您的示例,可以使用:

    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;
    

    使用这种方法,只是对函数使用引用,函数本身不会每次都重新创建。但是,在某些情况下,人们不能使用这样的方法并寻求其他解决方案。这里有多个这样的问题:

    How to pass variables to a function reference?

    【讨论】:

      猜你喜欢
      • 2011-05-02
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      相关资源
      最近更新 更多