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


简单的方法

使用箭头功能:

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

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

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

基本上,(对于任何不知道的人)由于onClick期望传递给它一个函数,所以bind可以工作,因为它创建了一个函数的副本。相反,我们可以传递一个箭头函数表达式,它只调用我们想要的函数,并保留它。您应该永远不需要在React中绑定渲染方法,但如果由于某种原因,您在某个组件方法中丢失了这一点:

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

class extends React.Component {
    onClickDiv = (column) => {
        // do stuff
    }
    render() {
        return <div onClick={() => this.onClickDiv('123')} />
    }
}

另一个不涉及.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演示,演示了该方法的实际操作。


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

});

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


我认为,React地图中的.bind(this,arg1,arg2,…)是错误的代码,因为它很慢!单个渲染方法中的.bind(this)的10-50-非常慢的代码。我是这样修复的:Render方法<tbody onClick={this.handleClickRow}><tr data id={listItem.id}>的映射处理程序var id=$(ev.target)最近('tr').data().id

完整代码如下:

类MyGrid扩展了React.Component{//实际上,我是从Redux中connect设置的道具中得到的状态={列表:[{id:1,姓名:“Mike”},{id:2,名称:“Bob”},{id:3,名称:“弗雷德”}],selectedItemId:3}渲染(){const{list,selectedItemId}=this.stateconst{handleClickRow}=此返回(<表><tbodyonClick={handleClickRow}>{list.map(listItem=>(<tr key={listItem.id}data id={listItem.id{className={selectedItemId==listItem.i?“selected”:“”}><td>{listItem.id}</td><td>{listItem.name}</td></tr>))}</tbody></table>)}handleClickRow=(ev)=>{常量目标=ev.target//您可以使用您想要查找的带有ID的TR,我使用jQueryconst数据集=$(target)最近('tr').data()if(!dataset||!dataset.id)返回this.setState({selectedItemId:+dataset.id})alert(dataset.id)//玩得开心!}}ReactDOM.render(<MyGrid/>,document.getElementById(“ReactDOM”))表{边界塌陷:塌陷;}.选定td{背景色:rgba(0,0,255,0.3);}<script src=“https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js“></script><script src=“https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js“></script><script src=“https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js“></script><div id=“react dom”></div>


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

在可单击元素中

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

然后

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

我对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>);}}


这里有很好的答案,我同意@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”/>


这个例子可能和你的有点不同。但我可以向你保证,这是解决这个问题的最佳方案。我已经找了好几天没有性能问题的解决方案。终于想出了这个。

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(对象)将其转换为字符串并添加到数据集。

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

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

我通过两种方式向方法添加了onclick事件值传递的代码。1.使用结合方法2。使用箭头(=>)方法。请参见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>);
    }
});

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

渲染链接(ES6)

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

组件功能

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

使用箭头功能:

您必须安装阶段2:

npm安装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; 

有三种方法可以处理此问题:-

将构造函数中的方法绑定为:-导出类HeaderRows扩展组件{构造器(){super();this.handleSort=this.handleSort.bind(this);}}将箭头函数创建为:-手柄端口=()=>{//这里有些文字}第三种方式是:-<th value={column}onClick={()=>that.handleSort}>{column}</th>


如果您正在使用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>
     );
   }
 }

通过将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中工作的确切场景。


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

我使用了es6语法。记住类内组件箭头函数不会自动绑定,所以在构造函数中显式绑定。

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

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


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

这是一个非常简单的方法。

 onClick={this.toggleStart('xyz')} . 
  toggleStart= (data) => (e) =>{
     console.log('value is'+data);  
 }

我意识到这已经很晚了,但我认为一个更简单的解决方案可以满足许多用例:

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

    ...

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

我想你也可以使用数据属性。

简单、语义。


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

您可以这样使用代码:

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

这里e表示事件对象,如果您想在句柄函数中使用preventDefault()之类的事件方法,或者想获得e.target.name之类的目标值或名称。


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

可以使用箭头函数环绕事件处理程序并传递参数:

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

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

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

除了这两种方法之外,还可以将参数传递给定义为咖喱函数的函数。

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

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

不知从何而来回答这个问题,但我认为,bind会奏效。找到下面的示例代码。

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

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

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

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

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

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

这样,我不需要将单元格的数据传递给处理程序,它可以自助处理。如果我需要更多的数据,不需要显示的数据,我可以使用dataset属性或隐藏元素。通过一些简单的DOM导航,一切都在手边。自从PC更容易陷入困境以来,HTML中就一直使用这种方式。


需要简单更改:

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

而不是<th value={column}onClick={that.handleSort}>{column}</th>


只需创建一个这样的函数

  function methodName(params) {
    //the thing  you wanna do
  }

在你需要的地方打电话

 <Icon onClick = {() => { methodName(theParamsYouwantToPass);} }/>

您只需要使用Arrow函数来传递值。

<buttonClick={()=>this.props.onClickHandle(“StackOverFlow”)}>

确保使用()=>,否则将在没有单击事件的情况下调用单击方法。

注意:崩溃检查默认方法

请在下面的codesandbox中找到相同的运行代码。

用方法反应传递值


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

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

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

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

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

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


React Hooks解决方案2022

const arr = [
  { id: 1, txt: 'One' },
  { id: 2, txt: 'Two' },
  { id: 3, txt: 'Three' },
]

const App = () => {
  const handleClick = useCallback(
    (id) => () => {
      console.log("ID: ", id)
    },
    [],
  )

  return (
    <div>
      {arr.map((item) => (
        <button onClick={handleClick(item.id)}>{item.txt}</button>
      ))}
    </div>
  )
}

您可以传递一个函数以使用Callback的返回,然后可以通过传递参数在渲染中正常调用函数!只需确保正确设置useCallback的依赖数组。

React>=16的最佳解决方案

我发现在不使用内联函数的情况下调用onClick、onChange等中具有多个参数的函数的最干净的方法是使用React 16和更高版本中提供的自定义数据属性。

const App = () => {
  const onClick = (e) => {
    const value1 = e.currentTarget.getAttribute("data-value1")
    const value2 = e.currentTarget.getAttribute("data-value2")
    const value2 = e.currentTarget.getAttribute("data-value2")
    console.log("Values1", value1)
    console.log("Values2", value2)
    console.log("Values3", value3)
  }
  return (
    <button onClick={onClick} data-value1="a" data-value2="b" data-value3="c" />
  )
}

上面的示例是针对功能组件的,但即使在类组件中,实现也非常相似。

这种方法不会产生不必要的重新渲染,因为您没有使用内联函数,并且可以避免使用这种方法绑定的麻烦。

它允许您在函数中传递任意数量的值。

如果要将值作为道具传递给子组件的onClick中使用的子组件,则也可以在那里使用此方法,而无需创建包装函数。

在您希望将对象的id传递给onClick的情况下,也可以使用对象数组,如下所示。

const App = () => {
  const [arrState, setArrState] = useState(arr)

  const deleteContent = (e) => {
    const id = e.currentTarget.getAttribute("data-id")
    const tempArr = [...arrState]
    const filteredArr = tempArr.filter((item) => item.id !== id)
    setArrState(filteredArr)
  }

  return (
    <div>
      {arrState.map((item) => (
        <React.Fragment key={item.id}>
          <p>{item.content}</p>
          <button onClick={deleteContent} data-id={item.id}>
            Delete
          </button>
        </React.Fragment>
      ))}
    </div>
  )
}

当使用函数而不是类时,这实际上相当容易。


    const [breakfastMain, setBreakFastMain] = useState("Breakfast");

const changeBreakfastMain = (e) => {
    setBreakFastMain(e.target.value);
//sometimes "value" won't do it, like for text, etc. In that case you need to 
//write 'e.target/innerHTML'
 }

<ul  onClick={changeBreakfastMain}>
   <li>
"some text here"
   </li>
<li>
"some text here"
   </li>
</ul>

使用this.handleSort。js中没有关键字。谢谢兄弟。

onClick={this.handleSort}

我会这样做:

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

可以在参数之间传递值

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

在这个场景中,我将列值传递给函数。