React js onClick无法将值传递给方法


637

我想阅读onClick事件值属性。但是当我单击它时,在控制台上会看到类似以下的内容:

SyntheticMouseEvent {dispatchConfig: Object, dispatchMarker: ".1.1.0.2.0.0:1", nativeEvent: MouseEvent, type: "click", target

我的代码正常工作。运行时,我可以{column}在onClick事件中看到但无法获取它。

我的代码:

var HeaderRows = React.createClass({
  handleSort:  function(value) {
    console.log(value);
  },
  render: function () {
    var that = this;
    return(
      <tr>
        {this.props.defaultColumns.map(function (column) {
          return (
            <th value={column} onClick={that.handleSort} >{column}</th>
          );
        })}
        {this.props.externalColumns.map(function (column) {
          // Multi dimension array - 0 is column name
          var externalColumnName = column[0];
          return ( <th>{externalColumnName}</th>);
        })}
      </tr>
    );
  }
});

如何onClick在React js中将值传递给事件?



2
考虑使用自我代替。这是相当令人误解的,因为它应该与“ this”(虽然对每个人来说并不重要)同义
Dan

使用bind方法和arrow方法,我们可以将值传递给Onclick事件
Merugu Prashanth

Answers:


1285

简单的方法

使用箭头功能:

return (
  <th value={column} onClick={() => this.handleSort(column)}>{column}</th>
);

这将创建一个新的函数,handleSort以正确的参数进行调用。

更好的方法

将其提取到子组件中。 在render调用中使用箭头函数的问题是,每次都会创建一个新函数,最终导致不必要的重新渲染。

如果创建子组件,则可以传递处理程序并将props用作参数,然后仅当props更改时才重新渲染(因为现在处理程序引用不再更改):

子组件

class TableHeader extends Component {
  handleClick = () => {
    this.props.onHeaderClick(this.props.value);
  }

  render() {
    return (
      <th onClick={this.handleClick}>
        {this.props.column}
      </th>
    );
  }
}

主要成分

{this.props.defaultColumns.map((column) => (
  <TableHeader
    value={column}
    onHeaderClick={this.handleSort}
  />
))}

旧的简便方法(ES5)

使用.bind通过所需要的参数:

return (
  <th value={column} onClick={that.handleSort.bind(that, column)}>{column}</th>
);

7
当我像您的代码一样使用时,react会发出警告。我将代码更改为onClick = {that.onClick.bind(null,column)}
user1924375 2015年

12
您如何将其与<a>需要传递事件的标签一起使用才能使用preventDefault()
Simon H

38
@SimonH该事件将作为您传递的参数之后的最后一个参数传递bind
涂抹

47
这对性能是否还不错?不会在每个渲染器上创建新功能吗?
AndrewMcLagan

13
@AndrewMcLagan是的。我发现这可以描述规则和最有效的解决方案。
E. Sundin

140

这里有很好的答案,我同意@Austin Greco(第二个选项,有单独的组件),
我喜欢另一种方式,currying
您可以做的是创建一个接受参数(您的参数)的函数并返回另一个接受另一个参数的函数(在这种情况下为click事件)。那么您就可以随心所欲地使用它。

ES5:

handleChange(param) { // param is the argument you passed to the function
    return function (e) { // e is the event object that returned

    };
}

ES6:

handleChange = param => e => {
    // param is the argument you passed to the function
    // e is the event object that returned
};

您将以这种方式使用它:

<input 
    type="text" 
    onChange={this.handleChange(someParam)} 
/>

这是此类用法的完整示例:

注意,这种方法不能解决在每个渲染器上创建新实例的问题。
与其他内联处理程序相比,我更喜欢这种方法,因为我认为这种方法更加简洁易读。

编辑:
如下面的注释中所建议,您可以缓存/记住函数的结果。

这是一个幼稚的实现:


12
这应该是公认的答案。真正易于实现,您无需创建任何其他组件或进行不同的绑定。谢谢!
Tamb

29
看起来更好,但是从性能的角度来看,currying并没有真正的帮助,因为如果您在相同的参数下两次调用handleChange,则会获得两个被JS引擎视为独立对象的函数,即使它们执行相同的操作。因此,您仍然可以重新渲染。为了提高性能,您需要缓存handleChange的结果以获得性能优势。喜欢handleChange = param => cache[param] || (e => { // the function body })
travellingprog

6
如果您满足@travellingprog的建议,这是一个完美的答案
llioor

2
谁能提供链接或解释此缓存机制的工作原理?谢谢。
Sadok Mtir

2
美丽而整洁!
Hatem Alimam '18

117

如今,有了ES6,我觉得我们可以使用更新的答案。

return (
  <th value={column} onClick={()=>this.handleSort(column)} >{column}</th>
);

基本上,(对于任何不知道的对象)由于onClick期望传递给它的功能而bind起作用,因为它创建了功能的副本。相反,我们可以传递一个箭头函数表达式,该表达式仅调用所需的函数并保留this。您永远不需要render在React中绑定该方法,但是如果由于某种原因您迷失this了一种组件方法:

constructor(props) {
  super(props);
  this.myMethod = this.myMethod.bind(this);
}

10
您不需要绑定,render()因为它是由React调用的。如果有的话,您需要bind事件处理程序,并且仅当您不使用箭头时。
丹·阿布拉莫夫

1
@DanAbramov我认为您是正确的,但为了以防万一,我将其包括在内-更新了一个示例,该示例未隐式鼓励绑定渲染。
aikeru'3

3
注意,最好在构造函数期间传递propssuper()this.props将其取消定义,否则可能会造成混淆。
Dan Abramov'3

2
要实现什么?您可以在功能组件内部定义处理程序并将其传递。每个渲染都会有不同的功能,因此,如果您已使用探查器确定它会给您带来性能问题(并且仅在您确实对此有把握的情况下!),请考虑使用类。
Dan Abramov

1
@ me-me是的,如果您选择在Babel中使用最前沿的JavaScript,则应该像在类上声明属性foo = () => {...},然后在render中引用,<button onClick={this.foo}...如果您以这种方式使用babel,则是唯一包含箭头功能的原因,IMO,如果您要捕获一些仅存在于render()方法范围内的变量(事件只能传递而不适用)。
aikeru

73

[[/ h到@ E.Sundin,以在评论中链接此内容 ]

最佳答案(匿名函数或绑定)将起作用,但它并不是最有效的方法,因为它会为函数生成的每个实例创建事件处理程序的副本map()

这是从ESLint-plugin-react中执行此操作的最佳方法的说明:

项目清单

渲染中bind的一个常见用例是渲染列表时,每个列表项都有一个单独的回调:

const List = props => (
      <ul>
        {props.items.map(item =>
          <li key={item.id} onClick={() => console.log(item.id)}>
            ...
          </li>
        )}
      </ul>
    );

而不是这样做,而是将重复的部分放入其自己的组件中:

const List = props => (
      <ul>
        {props.items.map(item =>
          <ListItem 
            key={item.id} 
            item={item} 
            onItemClick={props.onItemClick} // assume this is passed down to List
           />
        )}
      </ul>
    );


const ListItem = props => {
  const _onClick = () => {
    console.log(props.item.id);
  }
    return (
      <li onClick={_onClick}>
        ...
      </li>
    );

});

这将加速渲染,因为它避免了在每个渲染上创建新函数(通过绑定调用)的需要。


React是否会在后台使用call / apply调用这些函数,并避免在内部使用bind?
aikeru

1
有没有办法使用无状态组件来做到这一点?
卡洛斯·马丁内斯

2
@CarlosMartinez很好,我更新了示例-首先,它们应该是无状态功能组件(SFC)。通常,如果组件从未使用过this.state,则可以安全地将其与SFC交换掉。
布兰登

3
嗯,我不知道这怎么表现的更好?不会每次都调用ListItem函数,因此_onClick函数将在每次渲染时创建。
马提亚斯·佩特·约翰逊

1
我不是专家,但是据我了解,在“正确”模式下,只有处理程序的一个实例,并且无论组件调用哪个实例,它都通过了prop。在绑定示例(即“错误”模式)中,每个实例化组件都有一个处理程序实例。这种内存相当于将相同功能写入30次,然后再写入一次并在需要时调用它。
布兰登

25

这是我的方法,不确定是否有问题,请发表评论

在可点击元素中

return (
    <th value={column} onClick={that.handleSort} data-column={column}>   {column}</th>
);

然后

handleSort(e){
    this.sortOn(e.currentTarget.getAttribute('data-column'));
}

这是我一直在想的一种方法,虽然有点怪异,但却避免创建新组件。我不确定getAttribute是否比拉入一个单独的组件更好或更糟。
kamranicus

2
我认为这是一个很好的解决方案,因为它非常简单。但是,它仅适用于字符串值,如果您想要一个对象,它将不起作用。
斯蒂芬·L

对于对象,您需要先encodeURIComponent(JSON.stringify(myObj))进行解析,然后再解析JSON.parse(decodeURIComponent(myObj))。对于函数,我非常确定如果没有eval或new Function()都无法使用,则应避免两者。由于这些原因,我不使用数据属性在React / JS中传递数据。
Solvitieg '18

我想补充一点,我不经常使用此功能,仅将其用于次要功能。但是通常我只是创建一个组件并将数据作为道具传递给它。然后,要么处理该新组件内部的单击,要么将onClick函数传递给该组件。就像布兰登的答案中所解释的那样
圣地亚哥·拉米雷斯

1
可以在现代浏览器(包括IE11)上以这种方式直接访问数据集:e.currentTarget.dataset.column
gsziszi 18/10/21

17

此示例可能与您的示例稍有不同。但我可以向您保证,这是解决此问题的最佳解决方案。我已经搜索了几天,没有性能问题的解决方案。最后想出了这个。

class HtmlComponent extends React.Component {
  constructor() {
    super();
    this.state={
       name:'MrRehman',
    };
    this.handleClick= this.handleClick.bind(this);
  }

  handleClick(event) {
    const { param } = e.target.dataset;
    console.log(param);
    //do what you want to do with the parameter
  }

  render() {
    return (
      <div>
        <h3 data-param="value what you wanted to pass" onClick={this.handleClick}>
          {this.state.name}
        </h3>
      </div>
    );
  }
}

更新

如果您要处理应该作为参数的对象。您可以使用JSON.stringify(object)将其转换为字符串并添加到数据集中。

return (
   <div>
     <h3 data-param={JSON.stringify({name:'me'})} onClick={this.handleClick}>
        {this.state.name}
     </h3>
   </div>
);

1
当传递的数据是对象时,这将不起作用
SlimSim

使用JSON.stringify解决此问题。@SlimSim。应该可以解决问题的方法
汉娜·雷曼

如果您需要使用JSON.stringify解决此问题,那么它可能不是正确的方法。字符串化过程占用大量内存。
KFE

在大多数情况下,您只会将ID作为参数传递,并根据该ID从源对象中获取对象详细信息。以及为什么以及如何占用大量内存,我知道JSON stringify速度很慢,但是单击Fn是异步的,一旦构建
它将


4

不涉及.bindES6或ES6的另一个选择是使用带有处理程序的子组件,以使用必要的道具来调用父处理程序。这是一个示例(下面是工作示例的链接):

var HeaderRows = React.createClass({
  handleSort:  function(value) {
     console.log(value);
  },
  render: function () {
      var that = this;
      return(
          <tr>
              {this.props.defaultColumns.map(function (column) {
                  return (
                      <TableHeader value={column} onClick={that.handleSort} >
                        {column}
                      </TableHeader>
                  );
              })}
              {this.props.externalColumns.map(function (column) {
                  // Multi dimension array - 0 is column name
                  var externalColumnName = column[0];
                  return ( <th>{externalColumnName}</th>
                  );
              })}
          </tr>);
      )
  }
});

// A child component to pass the props back to the parent handler
var TableHeader = React.createClass({
  propTypes: {
    value: React.PropTypes.string,
    onClick: React.PropTypes.func
  },
  render: function () {
    return (
      <th value={this.props.value} onClick={this._handleClick}
        {this.props.children}
      </th>
    )        
  },
  _handleClick: function () {
    if (this.props.onClick) {
      this.props.onClick(this.props.value);
    }
  }
});

基本思想是父组件将onClick功能传递给子组件。子组件调用该onClick函数,并且可以访问props传递给它的任何函数(和event),从而允许您使用eventonClick函数中的任何值或其他属性。

这是一个CodePen演示,展示了此方法的实际作用。


4

我意识到这对于聚会来说还很晚,但是我认为更简单的解决方案可以满足许多用例:

    handleEdit(event) {
        let value = event.target.value;
    }

    ...

    <button
        value={post.id}
        onClick={this.handleEdit} >Edit</button>

我想您也可以使用data-属性。

简单,语义。



3

尝试尝试回答OP的问题,包括e.preventDefault()调用:

渲染链接(ES6

<a href="#link" onClick={(e) => this.handleSort(e, 'myParam')}>

组件功能

handleSort = (e, param) => {
  e.preventDefault();
  console.log('Sorting by: ' + param)
}

3

如果使用,您可以简单地做到这一点ES6

export default class Container extends Component {
  state = {
    data: [
        // ...
    ]
  }

  handleItemChange = (e, data) => {
      // here the data is available 
      // ....
  }
  render () {
     return (
        <div>
        {
           this.state.data.map((item, index) => (
              <div key={index}>
                  <Input onChange={(event) => this.handItemChange(event, 
                         item)} value={item.value}/>
              </div>
           ))
        }
        </div>
     );
   }
 }

3

如下所述,通过将count作为参数从主要组件传递到子组件来实现对象的总显示数量。

这是MainComponent.js

import React, { Component } from "react";

import SubComp from "./subcomponent";

class App extends Component {

  getTotalCount = (count) => {
    this.setState({
      total: this.state.total + count
    })
  };

  state = {
    total: 0
  };

  render() {
    const someData = [
      { name: "one", count: 200 },
      { name: "two", count: 100 },
      { name: "three", count: 50 }
    ];
    return (
      <div className="App">
        {someData.map((nameAndCount, i) => {
          return (
            <SubComp
              getTotal={this.getTotalCount}
              name={nameAndCount.name}
              count={nameAndCount.count}
              key={i}
            />
          );
        })}
        <h1>Total Count: {this.state.total}</h1>
      </div>
    );
  }
}

export default App;

这是 SubComp.js

import React, { Component } from 'react';
export default class SubComp extends Component {

  calculateTotal = () =>{
    this.props.getTotal(this.props.count);
  }

  render() {
    return (
      <div>
        <p onClick={this.calculateTotal}> Name: {this.props.name} || Count: {this.props.count}</p>
      </div>
    )
  }
};

尝试在上面实现,您将获得确切的场景,即传递参数如何在任何DOM方法上的reactjs中工作。


3

我编写了一个包装器组件,该组件可以在此基于已接受答案的基础上被重复使用。但是,如果您只需要传递一个字符串,则只需添加一个数据属性,然后从e.target.dataset中读取它即可(就像其他一些建议一样)。默认情况下,我的包装器将绑定到作为函数的任何prop,并且以“ on”开头,并在所有其他事件参数之后自动将数据prop返回给调用者。尽管我尚未对其性能进行测试,但它将为您提供避免自己创建类的机会,并且可以像这样使用它:

const DataButton = withData('button')
const DataInput = withData('input');

或用于组件和功能

const DataInput = withData(SomeComponent);

或者如果您愿意

const DataButton = withData(<button/>)

声明在您的容器外(在您的进口附近)

这是容器中的用法:

import withData from './withData';
const DataInput = withData('input');

export default class Container extends Component {
    state = {
         data: [
             // ...
         ]
    }

    handleItemChange = (e, data) => {
        // here the data is available 
        // ....
    }

    render () {
        return (
            <div>
                {
                    this.state.data.map((item, index) => (
                        <div key={index}>
                            <DataInput data={item} onChange={this.handleItemChange} value={item.value}/>
                        </div>
                    ))
                }
            </div>
        );
    }
}

这是包装器代码'withData.js:

import React, { Component } from 'react';

const defaultOptions = {
    events: undefined,
}

export default (Target, options) => {
    Target = React.isValidElement(Target) ? Target.type : Target;
    options = { ...defaultOptions, ...options }

    class WithData extends Component {
        constructor(props, context){
            super(props, context);
            this.handlers = getHandlers(options.events, this);        
        }

        render() {
            const { data, children, ...props } = this.props;
            return <Target {...props} {...this.handlers} >{children}</Target>;
        }

        static displayName = `withData(${Target.displayName || Target.name || 'Component'})`
    }

    return WithData;
}

function getHandlers(events, thisContext) {
    if(!events)
        events = Object.keys(thisContext.props).filter(prop => prop.startsWith('on') && typeof thisContext.props[prop] === 'function')
    else if (typeof events === 'string')
        events = [events];

    return events.reduce((result, eventType) => {
        result[eventType] = (...args) => thisContext.props[eventType](...args, thisContext.props.data);
        return result;
    }, {});
}

2

我在JSX onClick Events上对此有以下3条建议-

  1. 实际上,我们不需要在代码中使用.bind()或Arrow函数。您可以在代码中简单使用。

  2. 您还可以将onClick事件从th(或ul)移到tr(或li)以提高性能。基本上,您的n li个元素将具有n个“事件侦听器”。

    So finally code will look like this:
    <ul onClick={this.onItemClick}>
        {this.props.items.map(item =>
               <li key={item.id} data-itemid={item.id}>
                   ...
               </li>
          )}
    </ul>

    //你可以访问item.idonItemClick方法如下图所示:

    onItemClick = (event) => {
       console.log(e.target.getAttribute("item.id"));
    }
  3. 我同意上面提到的为ListItem和List创建单独的React Component的方法。这个make代码看起来不错,但是如果您有1000 li,那么将创建1000 Event Listeners。请确保您没有太多的事件侦听器。

    import React from "react";
    import ListItem from "./ListItem";
    export default class List extends React.Component {
    
        /**
        * This List react component is generic component which take props as list of items and also provide onlick
        * callback name handleItemClick
        * @param {String} item - item object passed to caller
        */
        handleItemClick = (item) => {
            if (this.props.onItemClick) {
                this.props.onItemClick(item);
            }
        }
    
        /**
        * render method will take list of items as a props and include ListItem component
        * @returns {string} - return the list of items
        */
        render() {
            return (
                <div>
                  {this.props.items.map(item =>
                      <ListItem key={item.id} item={item} onItemClick={this.handleItemClick}/>
                  )}
                </div>
            );
        }
    
    }
    
    
    import React from "react";
    
    export default class ListItem extends React.Component {
        /**
        * This List react component is generic component which take props as item and also provide onlick
        * callback name handleItemClick
        * @param {String} item - item object passed to caller
        */
        handleItemClick = () => {
            if (this.props.item && this.props.onItemClick) {
                this.props.onItemClick(this.props.item);
            }
        }
        /**
        * render method will take item as a props and print in li
        * @returns {string} - return the list of items
        */
        render() {
            return (
                <li key={this.props.item.id} onClick={this.handleItemClick}>{this.props.item.text}</li>
            );
        }
    }

1
当您需要传递的数据是对象时,这将不起作用。该属性仅适用于字符串。另外通过get属性从dom读取可能是更昂贵的操作。
SlimSim

2

我以两种方式为onclick事件值传递的代码添加了代码。1。使用bind方法2.使用arrow(=>)方法。参见方法handlesort1和handlesort

var HeaderRows  = React.createClass({
    getInitialState : function() {
      return ({
        defaultColumns : ["col1","col2","col2","col3","col4","col5" ],
        externalColumns : ["ecol1","ecol2","ecol2","ecol3","ecol4","ecol5" ],

      })
    },
    handleSort:  function(column,that) {
       console.log(column);
       alert(""+JSON.stringify(column));
    },
    handleSort1:  function(column) {
       console.log(column);
       alert(""+JSON.stringify(column));
    },
    render: function () {
        var that = this;
        return(
        <div>
            <div>Using bind method</div>
            {this.state.defaultColumns.map(function (column) {
                return (
                    <div value={column} style={{height : '40' }}onClick={that.handleSort.bind(that,column)} >{column}</div>
                );
            })}
            <div>Using Arrow method</div>

            {this.state.defaultColumns.map(function (column) {
                return (
                    <div value={column} style={{height : 40}} onClick={() => that.handleSort1(column)} >{column}</div>

                );
            })}
            {this.state.externalColumns.map(function (column) {
                // Multi dimension array - 0 is column name
                var externalColumnName = column;
                return (<div><span>{externalColumnName}</span></div>
                );
            })}

        </div>);
    }
});

2

下面是在onClick事件上传递值的示例。

我使用es6语法。记住在类组件中arrow函数不会自动绑定,因此在构造函数中显式绑定。

class HeaderRows extends React.Component {

    constructor(props) {
        super(props);
        this.handleSort = this.handleSort.bind(this);
    }

    handleSort(value) {
        console.log(value);
    }

    render() {
        return(
            <tr>
                {this.props.defaultColumns.map( (column, index) =>
                    <th value={ column } 
                        key={ index } 
                        onClick={ () => this.handleSort(event.target.value) }>
                        { column }
                    </th>
                )}

                {this.props.externalColumns.map((column, index)  =>
                    <th value ={ column[0] }
                        key={ index }>
                        {column[0]}
                    </th>
                )}
            </tr>
         );
    }
}

2

我猜您将不得不将方法绑定到React的类实例。使用构造函数绑定React中的所有方法比较安全。在您将参数传递给方法的情况下,第一个参数用于绑定方法的“ this”上下文,因此您无法访问方法内部的值。


2
1. You just have to use an arrow function in the Onclick event like this: 

<th value={column} onClick={() => that.handleSort(theValue)} >{column}</th>

2.Then bind this in the constructor method:
    this.handleSort = this.handleSort.bind(this);

3.And finally get the value in the function:
  handleSort(theValue){
     console.log(theValue);
}


2
class TableHeader extends Component {
  handleClick = (parameter,event) => {
console.log(parameter)
console.log(event)

  }

  render() {
    return (
      <button type="button" 
onClick={this.handleClick.bind(this,"dataOne")}>Send</button>
    );
  }
}

4
尽管这段代码可以解决问题,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。
Shree

2

这个问题冒出来,但我认为.bind可以解决。在下面找到示例代码。

const handleClick = (data) => {
    console.log(data)
}

<button onClick={handleClick.bind(null, { title: 'mytitle', id: '12345' })}>Login</button>

1

使用箭头功能:

您必须安装阶段2:

npm install babel-preset-stage-2:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value=0
        }
    }

    changeValue = (data) => (e) => {
        alert(data);  //10
        this.setState({ [value]: data })
    }

    render() {
        const data = 10;
        return (
            <div>
                <input type="button" onClick={this.changeValue(data)} />
            </div>
        );
    }
}
export default App; 

0

有3种方法可以解决这个问题:

  1. 将构造函数中的方法绑定为:

    export class HeaderRows extends Component {
       constructor() {
           super();
           this.handleSort = this.handleSort.bind(this);
       }
    }
  2. 在将箭头创建为时使用箭头功能:-

    handleSort = () => {
        // some text here
    }
  3. 第三种方式是这样的:

    <th value={column} onClick={() => that.handleSort} >{column}</th>

0

您可以这样使用代码:

<th value={column} onClick={(e) => that.handleSort(e, column)} >{column}</th>

如果您想使用事件preventDefault()函数(例如在handle函数中)或想要获取目标值或名称(如),则e用于事件对象e.target.name


0

我发现将param作为标签属性传递的解决方案非常合理。

但是它有局限性:

  • 当列表项具有其他标签时,此功能无法正常工作(因此event.target可能与预期的不同)
  • 参数只能是字符串。需要序列化和反序列化。

这就是为什么我想到了这个库:react-event-param

它:

  • 通过在需要时在父母中搜索所需的属性来解决孩子的问题
  • 自动序列化和反序列化参数
  • 封装设置和获取的逻辑。无需弄乱参数名称

用法示例:

import { setEventParam, getEventParam } from "react-event-param";

class List extends Component {
  onItemClick = e => {
    const index = getEventParam(e.target);
    // Do something with index
  };

  render() {
    return (
      <ul>
        {this.props.items.map((itemText, index) => (
          <li
            key={index}
            {...setEventParam(index)}
            onClick={this.onItemClick}
          >
            {{ itemText }}
          </li>
        ))}
      </ul>
    );
  }
}

export default List;

0

在真空中有很多性能方面的考虑。
该处理程序的问题在于,您需要对它们进行咖喱处理,以便将无法命名的参数纳入道具中。
这意味着该组件需要为每个可单击元素提供一个处理程序。让我们同意,对于几个按钮来说这不是问题,对吗?
当您处理具有数十列和数千行的表格数据时,会出现问题。在这里,您会注意到创建那么多处理程序的影响。

事实是,我只需要一个。
我在表级别(或UL或OL ...)上设置了处理程序,单击发生时,我可以使用事件对象中一直以来可用的数据来判断哪个是单击的单元格:

nativeEvent.target.tagName
nativeEvent.target.parentElement.tagName 
nativeEvent.target.parentElement.rowIndex
nativeEvent.target.cellIndex
nativeEvent.target.textContent

我使用标记名字段来检查单击是否发生在有效元素中,例如忽略页脚中的单击。
rowIndex和cellIndex给出单击的单元格的确切位置。
Textcontent是单击的单元格的文本。

这样,我不需要将单元格的数据传递给处理程序,它可以为它提供自助服务。
如果需要更多数据(不显示的数据),则可以使用数据集属性或隐藏元素。
有了一些简单的DOM导航,一切就在眼前。
自从PC变得更容易沼泽以来,就一直在HTML中使用它。


0

有两种方法可以在事件处理程序中传递参数,以下是一些方法。

您可以使用箭头函数来包装事件处理程序并传递参数:

<button onClick={() => this.handleClick(id)} />

上面的示例等效于调用.bind,也可以显式调用bind。

<button onClick={this.handleClick.bind(this, id)} />

除了这两种方法,您还可以将参数传递给定义为curry函数的函数。

handleClick = (id) => () => {
    console.log("Hello, your ticket number is", id)
};

<button onClick={this.handleClick(id)} />


-2

需要进行简单的更改:

采用 <th value={column} onClick={that.handleSort} >{column}</th>

代替 <th value={column} onClick={that.handleSort} >{column}</th>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.