我想读取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事件传递值?


当前回答

这里有很好的答案,我同意@Austin Greco(第二个选项,有单独的组件)还有一种我喜欢的方式,咖喱。您可以做的是创建一个接受一个参数(您的参数)的函数,并返回另一个接受另一个参数的函数(在本例中是单击事件)。那你就可以随心所欲了。

示例5:

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

以下是此类用法的完整示例:

const someArr=[“A”,“B”,“C”,“D”];类应用程序扩展React.Component{状态={值A:“”,valueB:“一些初始值”,值C:“”,值D:“废话”};handleChange=param=>e=>{const nextValue=e.target.value;this.setState({[“value”+param]:nextValue});};render(){返回(<div>{someArr.map(obj=>{返回(<div><标签>{`输入${obj}`}</label><输入type=“文本”value={this.state[“value”+obj]}onChange={this.handleChange(obj)}/><br/><br/></div>);})}</div>);}}const rootElement=document.getElementById(“root”);ReactDOM.render(<App/>,rootElement);<script src=“https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js“></script><script src=“https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js“></script><div id=“root”></div>

请注意,这种方法不能解决每次渲染时创建新实例的问题。与其他内联处理程序相比,我更喜欢这种方法,因为在我看来,这种方法更简洁、可读。

编辑:如下面的注释所示,您可以缓存/记忆函数的结果。

这是一个简单的实现:

让备忘录={};const someArr=[“A”,“B”,“C”,“D”];类应用程序扩展React.Component{状态={值A:“”,valueB:“一些初始值”,值C:“”,值D:“废话”};handleChange=param=>{常量处理程序=e=>{const nextValue=e.target.value;this.setState({[“value”+param]:nextValue});}if(!memo[param]){备忘录[param]=e=>处理程序(e)}返回备忘录[param]};render(){返回(<div>{someArr.map(obj=>{返回(<div key={obj}><标签>{`输入${obj}`}</label><输入type=“文本”value={this.state[“value”+obj]}onChange={this.handleChange(obj)}/><br/><br/></div>);})}</div>);}}const rootElement=document.getElementById(“root”);ReactDOM.render(<App/>,rootElement);<script src=“https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js“></script><script src=“https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js“></script><div id=“root”/>

其他回答

这是我的方法,不知道有多糟糕,请评论

在可单击元素中

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

然后

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

我编写了一个包装器组件,可用于此目的,该组件基于此处接受的答案。如果你只需要传递一个字符串,那么只需添加一个数据属性并从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;
    }, {});
}

简单的方法

使用箭头功能:

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

这将创建一个新函数,该函数使用正确的参数调用handleSort。

更好的方式

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

如果创建子组件,则可以传递处理程序并使用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传递所需的参数,这样可以将函数与Component上下文绑定:

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

我会这样做:

const HeaderRows = props => {
    const handleSort = value => () => {

    }

    return <tr>
        {props.defaultColumns.map((column, i) =>
            <th key={i} onClick={handleSort(column)}>{column}</th>)}
        {props.externalColumns.map((column, i) => {
            // Multi dimension array - 0 is column name
            const externalColumnName = column[0]
            return (<th key={i}>{externalColumnName}</th>)
        })}
    </tr>
}

使用封口,可获得干净的解决方案:

<th on单击={this.handleSort(column)}>{column}</th>

handleSort函数将返回已设置值列的函数。

handleSort: function(value) { 
    return () => {
        console.log(value);
    }
}

当用户单击th时,将使用正确的值调用匿名函数。

例子:https://stackblitz.com/edit/react-pass-parameters-example