首页 文章

React JS onClick事件处理程序

提问于
浏览
90

我有

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

9 回答

  • 60
    import React from 'react';
    
    class MyComponent extends React.Component {
    
      getComponent(event) {
          event.target.style.backgroundColor = '#ccc';
          
          // or you can write
          //arguments[0].target.style.backgroundColor = '#ccc';
      }
    
      render() {
        return(
           <div>
             <ul>
                <li onClick={this.getComponent.bind(this)}>Component 1</li>
             </ul>
           </div>
        );
      }
    }
    
    export { MyComponent };  // use this to be possible in future imports with {} like: import {MyComponent} from './MyComponent'
    export default MyComponent;
    
  • 2

    您可以使用React.createClone方法 . 创建元素,而不是创建它的克隆 . 在克隆创建过程中,您可以注入道具 . 像这样注入一个onClick:方法道具

    { onClick : () => this.changeColor(originalElement, index) }

    changeColor方法将使用副本设置状态,允许您在进程中设置颜色 .

    render()
      {
        return(
          <ul>
    
            {this.state.items.map((val, ind) => {
              let item = <li key={ind}>{val}</li>;
              let props = { 
                onClick: () => this.Click(item, ind),
                key : ind,
                ind
              }
              let clone = React.cloneElement(item, props, [val]);
              return clone;
            })}
    
          </ul>
        )
      }
    
  • 11

    为什么不呢:

    onItemClick: function (event) {
    
        event.currentTarget.style.backgroundColor = '#ccc';
    
    },
    
    render: function() {
        return (
            <div>
                <ul>
                    <li onClick={this.onItemClick}>Component 1</li>
                </ul>
            </div>
        );
    }
    

    如果你想更多关于它的反应,你可能想要将所选项目设置为其包含的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> 放入循环中,你需要让 li.onli.off 样式设置你的 background-color .

  • -14

    我能想到的两种方式是

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

    这是DEMO

    我希望这有帮助 .

  • 71

    以下是如何使用es6语法定义一个响应onClick事件处理程序,它正在回答问题 Headers

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

    使用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'));`
    
  • 1

    如果你使用的是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;
    

    请注意,每个动态创建的元素都应具有唯一的引用“key” .

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

    新的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>
        )}
    )}
    
  • 30

    使用React元素处理事件与处理DOM元素上的事件非常相似 . 存在一些语法差异:React事件使用camelCase命名,而不是小写 . 使用JSX,您可以将函数作为事件处理程序而不是字符串传递 .

    正如 React 文档中提到的,它们与事件处理方面的普通HTML非常相似,但是React中的事件名称使用了camelcase,因为它们不是真正的HTML,它们是JavaScript,你在我们传递函数调用时传递函数在HTML的字符串格式中,它们是不同的,但概念非常相似......

    看下面的例子,注意事件传递给函数的方式:

    function ActionLink() {
      function handleClick(e) {
        e.preventDefault();
        console.log('The link was clicked.');
      }
    
      return (
        <a href="#" onClick={handleClick}>
          Click me
        </a>
      );
    }
    
  • 1

    请注意,如果你downvote . 这是一个非标准的(但并非罕见的)React模式,它不会产生Coffeescript .

    执行此操作的“反应方式”将是组件自身的状态:

    c = console.log.bind console

    mock_items: [
        {
            name: 'item_a'
            uid: shortid()
        }
        {
            name: 'item_b'
            uid: shortid()
        }
        {
            name: 'item_c'
            uid: shortid()
        }
    ]
    getInitialState: ->
        lighted_item: null
    render: ->
        div null,
            ul null,
                for item, idx in @mock_items
                    uid = item.uid
                    li
                        key: uid
                        onClick: do (idx, uid) =>
                            (e) =>
                                # justf to illustrate these are bound in closure by the do lambda,
                                c idx
                                c uid
                                @setState
                                    lighted_item: uid
                        style:
                            cursor: 'pointer'
                            background: do (uid) =>
                                c @state.lighted_item
                                c 'and uid', uid
                                if @state.lighted_item is uid then 'magenta' else 'chartreuse'
                            # background: 'chartreuse'
                        item.name
    

    这个例子有效 - 我在本地测试了它 . 您可以在my github查看此示例代码 . 最初env只是我自己的白板研发目的本地,但我把它发布到Github为此 . 可能会在某些时候写完,但您可以查看2016年9月8日的提交以查看此内容 .

    更一般地说,如果你想看看React的CS / no-JSX模式是如何工作的,请查看最近的一些工作here . 我有可能有时间为这个app想法完全实现POC,其中包括NodeJS,Primus,Redis和React .

相关问题