React JS onClick 事件处理程序

IT技术 javascript jquery reactjs
2021-02-16 05:16:12

我有

var TestApp = React.createClass({
      getComponent: function(){
          console.log(this.props);
      },
      render: function(){
        return(
             <div>
             <ul>
                <li onClick={this.getComponent}>Component 1</li>
             </ul>
             </div>
        );
      }
});
React.renderComponent(<TestApp />, document.body);

我想为单击的列表元素的背景着色。我怎样才能在 React 中做到这一点?

就像是

$('li').on('click', function(){
    $(this).css({'background-color': '#ccc'});
});
6个回答

为什么不:

onItemClick: function (event) {

    event.currentTarget.style.backgroundColor = '#ccc';

},

render: function() {
    return (
        <div>
            <ul>
                <li onClick={this.onItemClick}>Component 1</li>
            </ul>
        </div>
    );
}

并且如果您想对其进行更多react,您可能希望将所选项目设置为其包含 React 组件的状态,然后引用该状态以确定项目的颜色render

onItemClick: function (event) {

    this.setState({ selectedItem: event.currentTarget.dataset.id });
    //where 'id' =  whatever suffix you give the data-* li attribute
},

render: function() {
    return (
        <div>
            <ul>
                <li onClick={this.onItemClick} data-id="1" className={this.state.selectedItem == 1 ? "on" : "off"}>Component 1</li>
                <li onClick={this.onItemClick} data-id="2" className={this.state.selectedItem == 2 ? "on" : "off"}>Component 2</li>
                <li onClick={this.onItemClick} data-id="3" className={this.state.selectedItem == 3 ? "on" : "off"}>Component 3</li>
            </ul>
        </div>
    );
},

您想将这些<li>s 放入循环中,并且需要将li.onli.off样式设置为您的background-color.

React 中的手动 DOM 操作是一种反模式,只会导致更多问题。避免使用类似的东西,event.currentTarget.style.backgroundColor = '#ccc';除非您真正了解自己在做什么(大多数情况下,在集成第三方小部件时)。
2021-04-19 05:16:12

我能想到的两种方法是

var TestApp = React.createClass({
    getComponent: function(index) {
        $(this.getDOMNode()).find('li:nth-child(' + index + ')').css({
            'background-color': '#ccc'
        });
    },
    render: function() {
        return (
            <div>
              <ul>
                <li onClick={this.getComponent.bind(this, 1)}>Component 1</li>
                <li onClick={this.getComponent.bind(this, 2)}>Component 2</li>
                <li onClick={this.getComponent.bind(this, 3)}>Component 3</li>
              </ul>
            </div>
        );
    }
});
React.renderComponent(<TestApp /> , document.getElementById('soln1'));

这是我个人的最爱。

var ListItem = React.createClass({
    getInitialState: function() {
        return {
            isSelected: false
        };
    },
    handleClick: function() {
        this.setState({
            isSelected: true
        })
    },
    render: function() {
        var isSelected = this.state.isSelected;
        var style = {
            'background-color': ''
        };
        if (isSelected) {
            style = {
                'background-color': '#ccc'
            };
        }
        return (
            <li onClick={this.handleClick} style={style}>{this.props.content}</li>
        );
    }
});

var TestApp2 = React.createClass({
    getComponent: function(index) {
        $(this.getDOMNode()).find('li:nth-child(' + index + ')').css({
            'background-color': '#ccc'
        });
    },
    render: function() {
        return (
            <div>
             <ul>
              <ListItem content="Component 1" />
              <ListItem content="Component 2" />
              <ListItem content="Component 3" />
             </ul>
            </div>
        );
    }
});
React.renderComponent(<TestApp2 /> , document.getElementById('soln2'));

这是一个演示

我希望这有帮助。

@jony89 同意如果.bind不带额外参数。但在第一种情况下确实如此。我不认为有另一种方式
2021-04-22 05:16:12
不建议在渲染函数中应用绑定,因为它会在每次渲染组件时执行。您可以将其移动到某个在生命周期开始时运行的函数
2021-05-08 05:16:12
有,创建三个不同的函数(由 getComponent.bind(this, 1) 的结果创建),尽管这个确定可以是一个决定(将它用于 2-3 个组件,而不是 20 个 - 除非它真的是性能问题并且易于动态创建)。
2021-05-09 05:16:12

这是您定义react onClick 事件处理程序的方法,它使用 es6 语法回答问题标题...

import React, { Component } from 'react';

export default class Test extends Component {
  handleClick(e) {
    e.preventDefault()
    console.log(e.target)
  }

  render() {
    return (
      <a href='#' onClick={e => this.handleClick(e)}>click me</a>
    )
  }
}
既不bind也不箭头函数应该内使用render的方法,因为它们导致在每个时间正在创建新功能。这会改变组件的状态,并且总是重新渲染具有更改状态的组件。对于单身人士来说,a这没什么大不了的。对于带有可点击项目的生成列表,这很快就会成为一个大问题。这就是为什么要特别警告它的原因。
2021-04-28 05:16:12

使用 ECMA2015。箭头函数使“this”更加直观。

import React from 'react';


class TestApp extends React.Component {
   getComponent(e, index) {
       $(e.target).css({
           'background-color': '#ccc'
       });
   }
   render() {
       return (
           <div>
             <ul>
               <li onClick={(e) => this.getComponent(e, 1)}>Component 1</li>
               <li onClick={(e) => this.getComponent(e, 2)}>Component 2</li>
               <li onClick={(e) => this.getComponent(e, 3)}>Component 3</li>
             </ul>
           </div>
       );
   }
});
React.renderComponent(<TestApp /> , document.getElementById('soln1'));`
@northamerican - 不,它只是为了增加一些参数清晰度
2021-04-22 05:16:12
这实际上对性能不利,因为它在每次渲染时都会创建一个新函数。参见:stackoverflow.com/questions/36677733/...
2021-04-26 05:16:12
index 在这里什么都不做?
2021-05-11 05:16:12
如果非必要,请不要在 React 中使用 jQuery!
2021-05-12 05:16:12

如果您使用的是 ES6,这里有一些简单的示例代码:

import React from 'wherever_react_is';

class TestApp extends React.Component {

  getComponent(event) {
      console.log('li item clicked!');
      event.currentTarget.style.backgroundColor = '#ccc';
  }

  render() {
    return(
       <div>
         <ul>
            <li onClick={this.getComponent.bind(this)}>Component 1</li>
         </ul>
       </div>
    );
  }
}

export default TestApp;

在 ES6 类体中,函数不再需要 'function' 关键字,也不需要用逗号分隔。如果您愿意,您也可以使用 => 语法。

下面是一个动态创建元素的例子:

import React from 'wherever_react_is';

class TestApp extends React.Component {

constructor(props) {
  super(props);

  this.state = {
    data: [
      {name: 'Name 1', id: 123},
      {name: 'Name 2', id: 456}
    ]
  }
}

  getComponent(event) {
      console.log('li item clicked!');
      event.currentTarget.style.backgroundColor = '#ccc';
  }

  render() {        
       <div>
         <ul>
         {this.state.data.map(d => {
           return(
              <li key={d.id} onClick={this.getComponent.bind(this)}>{d.name}</li>
           )}
         )}
         </ul>
       </div>
    );
  }
}

export default TestApp;

请注意,每个动态创建的元素都应该有一个唯一的引用“键”。

此外,如果您想将实际数据对象(而不是事件)传递到您的 onClick 函数中,您需要将其传递到您的绑定中。例如:

新的点击功能:

getComponent(object) {
    console.log(object.name);
}

传入数据对象:

{this.state.data.map(d => {
    return(
      <li key={d.id} onClick={this.getComponent.bind(this, d)}>{d.name}</li>
    )}
)}
我刚刚找到了一个类似的答案,您需要使用 .bind(this)); 在匿名函数的末尾,因为 this 在这里指的是窗口,直到您进行绑定...
2021-04-18 05:16:12
我正在尝试动态构建我的 li 项目,然后这看起来变得未定义,因此 onClick 函数会引发错误。
2021-04-28 05:16:12