我想读取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>
    );
  }
});

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


当前回答

我编写了一个包装器组件,可用于此目的,该组件基于此处接受的答案。如果你只需要传递一个字符串,那么只需添加一个数据属性并从e.target.dataset中读取它(就像其他人建议的那样)。默认情况下,我的包装器将绑定到任何以“on”开头的属性,并在所有其他事件参数之后自动将数据属性传递回调用者。虽然我还没有测试过它的性能,但它会让您有机会避免自己创建类,并且可以这样使用:

const DataButton=带数据(“按钮”)

const DataInput=with Data('input');

或组件和功能

const DataInput=with Data(SomeComponent);

或者如果你愿意

const DataButton=with Data(<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;
    }, {});
}

其他回答

[[h/t发送至@E.Sundin,以便在评论中链接此内容]

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

这是对ESLint插件反应最佳方式的解释:

项目列表渲染中绑定的一个常见用例是在渲染列表时每个列表项的单独回调:

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

});

这将加快渲染速度,因为它避免了创建新的函数(通过绑定调用)。

class extends React.Component {
    onClickDiv = (column) => {
        // do stuff
    }
    render() {
        return <div onClick={() => this.onClickDiv('123')} />
    }
}
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);
}

我对JSX onClick事件有以下3点建议-

实际上,我们不需要在代码中使用.bind()或Arrow函数。您可以在代码中简单使用。您还可以将onClick事件从th(或ul)移动到tr(或li)以提高性能。基本上,您的n li元素将有n个“事件侦听器”。所以最后代码将如下所示:<ul onClick={this.onItemClick}>{this.props.items.map(item=><li key={item.id}data itemid={item.id}}>...</li>)}</ul>//您可以在onItemClick方法中访问item.id,如下所示:onItemClick=(事件)=>{console.log(e.target.getAttribute(“item.id”));}我同意上面提到的为ListItem和List创建单独的React组件的方法。然而,如果您有1000个li,那么将创建1000个Event Listener,这使得代码看起来很好。请确保您不应该有太多的事件侦听器。从“React”导入React;从“./ListItem”导入ListItem;导出默认类List扩展React.Component{/***这个List-react组件是一个通用组件,它将道具作为物品列表,并提供onlick*回调名称handleItemClick*@param{String}item-传递给调用者的item对象*/handleItemClick=(项)=>{if(this.props.onItemClick){this.props.onItemClick(项);}}/***render方法将项目列表作为道具,并包含ListItem组件*@returns{string}-返回项目列表*/render(){返回(<div>{this.props.items.map(item=><ListItem key={item.id}item={item}onItemClick={this.handleItemClick}/>)}</div>);}}从“React”导入React;导出默认类ListItem扩展React.Component{/***这个List-react组件是一个通用组件,它将道具作为物品,并提供onlick*回调名称handleItemClick*@param{String}item-传递给调用者的item对象*/handleItemClick=()=>{if(this.props.item&&this.props.onItemClick){this.props.onItem单击(this.props.项);}}/***render方法将项目作为道具,并在li中打印*@returns{string}-返回项目列表*/render(){返回(<li key={this.props.item.id}onClick={this.handleItemClick}>{this.props.item.text}</li>);}}

另一个不涉及.bind或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函数,可以访问传递给它的任何属性(以及事件),允许您在父组件的onClick功能中使用任何事件值或其他属性。

下面是一个CodePen演示,演示了该方法的实际操作。