ChatGPT解决这个技术问题 Extra ChatGPT

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

我想阅读 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 事件?

考虑使用 self 而不是那个。这是相当误导的,因为它应该是“这个”的同义词(虽然并不重要,但对每个人来说都是如此)
使用绑定方法和箭头方法,我们可以将值传递给 Onclick 事件
同意@WiredPrairie 和名叫 ZenMaster 的人准确有效地解释。
你做错了什么是将调用的返回值传递给handleSort,当然,它发生在页面加载时

t
theSereneRebel

简单的方法

使用箭头函数:

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

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

更好的方法

Extract it into a sub-component. 在渲染调用中使用箭头函数的问题在于,它每次都会创建一个新函数,最终导致不必要的重新渲染。

如果你创建一个子组件,你可以传递 handler 并使用 props 作为参数,然后只有当 props 改变时才会重新渲染(因为 handler 引用现在永远不会改变):

子组件

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={this.handleSort.bind(this, column)}>{column}</th>
);

当我像您的代码一样使用时,反应会发出警告。我将代码更改为 onClick={that.onClick.bind(null,column)}
您如何将它与需要传递事件的 <a> 标记一起使用,以便使用 preventDefault()
@SimonH 该事件将作为最后一个参数传递,在您通过 bind 传递的参数之后。
这不利于性能吗?不会在每次渲染上创建一个新函数吗?
@AndrewMcLagan 是的。我found this来描述规则和最高效的解决方案。
S
Sagiv b.g

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

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

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

const someArr = ["A", "B", "C", "D"];类 App 扩展 React.Component { state = { valueA: "", valueB: "一些初始值", valueC: "", valueD: "blah blah" }; handleChange = 参数 => e => { const nextValue = e.target.value; this.setState({ ["value" + param]: nextValue }); }; render() { return (

{someArr.map(obj => { return (


); })}
); } } const rootElement = document.getElementById("root"); ReactDOM.render(, rootElement);

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

编辑:正如下面评论中所建议的,您可以缓存/记忆函数的结果。

这是一个幼稚的实现:

让备忘录 = {}; const someArr = ["A", "B", "C", "D"];类 App 扩展 React.Component { state = { valueA: "", valueB: "一些初始值", valueC: "", valueD: "blah blah" }; handleChange = param => { const handler = e => { const nextValue = e.target.value; this.setState({ ["value" + param]: nextValue }); } if (!memo[param]) { memo[param] = e => handler(e) } return memo[param] }; render() { return (

{someArr.map(obj => { return (


); })}
); } } const rootElement = document.getElementById("root"); ReactDOM.render(, rootElement);


这应该是公认的答案。真的很容易实现,你不需要创建任何其他组件或以不同的方式绑定。谢谢!
看起来更好,但是从性能的角度来看,currying 并没有真正的帮助,因为如果您使用相同的参数调用 handleChange 两次,您将获得 JS 引擎认为是独立对象的两个函数,即使它们做同样的事情.所以你仍然得到重新渲染。为了性能,您需要缓存 handleChange 的结果以获得性能优势。喜欢handleChange = param => cache[param] || (e => { // the function body })
如果您满足@travellingprog 的建议,这是完美的答案
任何人都可以提供链接或解释这种缓存机制是如何工作的吗?谢谢。
如果使用柯里化,每次渲染都会创建新函数。与传递箭头函数相同的性能问题。
a
aikeru

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

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

基本上,(对于任何不知道的人)因为 onClick 期望传递给它的函数,所以 bind 之所以有效,是因为它创建了一个函数的副本。相反,我们可以传递一个箭头函数表达式,它简单地调用我们想要的函数,并保留 this。您永远不需要在 React 中绑定 render 方法,但如果由于某种原因您在某个组件方法中丢失了 this

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

您永远不需要绑定 render(),因为它是由 React 调用的。如果有的话,您需要 bind 事件处理程序,并且仅当您不使用箭头时。
请注意,最好将 props 传递给 super(),否则 this.props 将在构造函数期间未定义,这可能会让人感到困惑。
达到什么目的?您可以在功能组件内定义一个处理程序并传递它。每次渲染都会有不同的功能,因此如果您使用分析器确定它会给您带来性能问题(并且只有当您确实确定这一点时!),请考虑改用类。
谢谢艾克鲁。啊,好吧,所以你是说如果你将 foo 方法声明为类本身的箭头函数,然后使用 this 上下文引用它,然后它只创建一次,而不是在 onClick 中声明它,每次点击它都会创建相同的函数按钮。我的想法是否正确。
@zuckerburg onClick={() => alert('hi')} 不会立即发出警报, onClick={this.showAlert} 也不会,因为在这两种情况下,您都在传递(而不是调用)一个函数。
B
Brandon

[[h/t 给 @E.Sundin 的 linking this 在评论中]

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

这是对 ESLint-plugin-react 的最佳方法的解释:

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

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 调用这些函数,并避免在内部使用绑定?
有没有办法使用无状态组件来做到这一点?
@CarlosMartinez 好眼光,我更新了示例——它们首先应该是无状态功能组件(SFC)。通常,如果某个组件从不使用 this.state,您可以安全地将其换成 SFC。
嗯,我不明白这是如何提高性能的?不会每次都调用 ListItem 函数,因此每次渲染都会创建 _onClick 函数。
我在这里远非专家,但据我了解,在“正确”模式中,只有一个处理程序实例,并且它传递了组件调用它的任何实例的道具。在绑定示例(即“错误”模式)中,每个实例化组件都有一个处理程序实例。这相当于将相同的函数编写 30 次,而不是编写一次并在需要时调用它。
S
Santiago Ramirez

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

在可点击元素中

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

接着

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

这是我正在考虑的一种方法,感觉有点hacky,但避免创建新组件。与拉入单独的组件相比,我不确定 getAttribute 在性能方面是更好还是更差。
我认为这是一个很好的解决方案,因为它非常简单。但它只适用于字符串值,如果你想要一个对象它不起作用。
对于一个对象,您需要执行 encodeURIComponent(JSON.stringify(myObj)),然后解析它,JSON.parse(decodeURIComponent(myObj))。对于函数,我很确定如果没有 eval 或 new Function(),这将无法工作,这两者都应该避免。由于这些原因,我不使用数据属性在 React/JS 中传递数据。
我想补充一下,我不经常使用它,只用于次要的事情。但通常我只是创建一个组件并将数据作为道具传递给它。然后要么处理该新组件内的点击,要么将 onClick 函数传递给组件。就像布兰登回答中解释的那样
在现代浏览器(包括 IE11)上可以通过这种方式直接访问数据集:e.currentTarget.dataset.column
r
ravibagul91

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

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

当传递的数据是对象时,这不起作用
使用 JSON.stringify 解决问题。 @SlimSim。这应该够了吧
如果您需要使用 JSON.stringify 来解决这个问题,那么它可能不是正确的方法。字符串化的过程会占用大量内存。
在大多数情况下,您只会将 ID 作为参数传递,并根据该 ID 从源对象中获取对象详细信息。以及为什么以及如何占用大量内存,我知道 JSON stringify 很慢,但是单击 Fn 是异步的,一旦构建,它将对 dom 没有影响或为 0
T
Tom Bombadil

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

您可以将一个函数传递给 useCallback 的返回,然后您可以通过将参数传递给它来在渲染中正常调用您的函数。奇迹般有效!只需确保正确设置了 useCallback 的依赖数组即可。

React >= 16 的最佳解决方案

我发现在 onClick、onChange 等中调用具有多个参数的函数而不使用内联函数的最简洁方法是使用 React 16 及更高版本中可用的自定义 data 属性。

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

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

这种方法不会产生不必要的重新呈现,因为您没有使用内联函数,并且您避免了与 this 绑定的麻烦。

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

如果您将值作为道具传递给您的子组件以在子组件的 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>
  )
}

我喜欢这个 data- 评论。如此干净和简单
实际上,在您的示例中使用 useEffect 无济于事,因为 useCallback 返回的回调仍会在每次渲染时创建新函数。
@MarcesEngel 取决于您传递给 useCallback 数组的内容。
@TomBombadil 你会详细说明吗?只有外部函数的创建被记忆,而不是它的结果。这意味着返回的函数将在每次执行时创建一个新函数,在这种情况下,每次渲染包含的组件。这个思路有毛病吗?
@MarcesEngel 是的,您可能是对的。但是在我工作的地方,这些项目有严格的 ES Lint 规则,所以没有内联函数。第一个肯定可以安抚 ES Lint。此外,我并没有真正提到任何关于性能改进的事情。只是这也是一种方式。我通常会选择第二个。多一点工作,但在大多数情况下有效。您可以 toString 整个对象并将其传递给第二个。也许很愚蠢,但是 React.FC 并没有真正给我们很多关于将参数传递给 JSX 中的函数的信息。
C
Charith Jayasanka

只需创建一个这样的函数

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

并在你需要的地方调用它

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

哦😶😶😶😶😶😶
哈哈哈,这很有效!你甚至不需要花括号和括号。任何人都知道 React 如何在这里处理匿名函数?
V
Vladimirs Matusevics
class extends React.Component {
    onClickDiv = (column) => {
        // do stuff
    }
    render() {
        return <div onClick={() => this.onClickDiv('123')} />
    }
}

相同的 - 每个渲染上的新 DOM。所以 React 每次都会更新 DOM。
j
jhchnc

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

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

    ...

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

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

简单,语义。


P
Po Rith

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

渲染链接 (ES6)

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

组件功能

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

B
Brett DeWoody

不涉及 .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 函数并可以访问传递给它的任何 props(和 event),从而允许您在父 onClick 函数中使用任何 event 值或其他道具。

下面的 CodePen demo 显示了此方法的实际效果。


P
Pramesh Bajracharya

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

n
nandu

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

这是 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 中工作的确切场景。


U
Umair Ahmed

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

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

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

S
SlimSim

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

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

T
Tom Fuller

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

实际上,我们不需要在代码中使用 .bind() 或 Arrow 函数。您可以在代码中简单使用。您还可以将 onClick 事件从 th(或 ul)移动到 tr(或 li)以提高性能。基本上,您的 n li 元素将有 n 个“事件侦听器”。所以最后代码看起来像这样:

    {this.props.items.map(item =>
  • 。 ..
  • )}
// 并且可以在 onItemClick 方法中访问 item.id 如下所示: onItemClick = (event) => { console.log(e.target.getAttribute("item.id "));我同意上面提到的为 ListItem 和 List 创建单独的 React 组件的方法。这使代码看起来不错,但是如果您有 1000 个 li,那么将创建 1000 个事件侦听器。请确保您不应该有太多的事件监听器。从“反应”导入反应;从“./ListItem”导入 ListItem; export default class List extends React.Component { /** * 此 List react 组件是通用组件,它以 props 作为项目列表并提供 onlick * 回调名称 handleItemClick * @param {String} item - 传递给调用者的项目对象 */ handleItemClick = (item) => { if (this.props.onItemClick) { this.props.onItemClick(item); } } /** * render 方法将项目列表作为道具并包含 ListItem 组件 * @returns {string} - 返回项目列表 */ render() { return (
{this.props.items. map(item => )}
); } } 从“反应”导入反应; export default class ListItem extends React.Component { /** * 这个 List 反应组件是通用组件,它以 props 作为项目,还提供 onlick * 回调名称 handleItemClick * @param {String} item - 传递给调用者的项目对象 */ handleItemClick = () => { if (this.props.item && this.props.onItemClick) { this.props.onItemClick(this.props.item); } } /** * render 方法将 item 作为 props 并在 li 中打印 * @returns {string} - 返回项目列表 */ render() { return (
  • {this.props.item.text}
  • ); } }


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

    我以两种方式添加了用于将 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>);
        }
    });
    

    P
    Pang

    下面是在 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>
             );
        }
    }
    

    A
    Andysenclave

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


    J
    Juan David Arce
    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);
    }
    

    M
    Mario Petrovic

    使用箭头功能:

    您必须安装第 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; 
    

    R
    Romia Mukherjee

    有一个非常简单的方法。

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

    A
    Anik Mazumder
    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>
        );
      }
    }
    

    虽然此代码可以解决问题,但 including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。
    C
    Charitha Goonewardena

    突然出现这个问题,但我认为 .bind 会解决问题。找到下面的示例代码。

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

    H
    Hiren Gohel

    有3种方法来处理这个: -

    将构造函数中的方法绑定为:- export class HeaderRows extends Component { constructor() { super(); this.handleSort = this.handleSort.bind(this); } } 创建时使用箭头函数:- handleSort = () => { // 这里有一些文本 } 第三种方式是这样的:- that.handleSort} > {列}


    T
    Tiw

    您可以像这样使用您的代码:

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

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


    J
    Juan Lanus

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

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

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

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

    这样我就不需要将单元格的数据传递给处理程序,它可以自助服务。如果我需要更多数据,即不显示的数据,我可以使用数据集属性或隐藏元素。通过一些简单的 DOM 导航,一切都触手可及。从那时起,这一直在 HTML 中使用,因为 PC 更容易陷入困境。


    你提出了一个非常重要的问题——性能考虑!
    y
    yfalik

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

    
        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>
    

    f
    francis

    我会这样做:

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