Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/185.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 向React.DOM元素动态添加事件处理程序_Reactjs - Fatal编程技术网

Reactjs 向React.DOM元素动态添加事件处理程序

Reactjs 向React.DOM元素动态添加事件处理程序,reactjs,Reactjs,我正在使用RadioButtonGroup组件,该组件类似于单选输入,但带有按钮: 如果组件的使用像这样简单就好了: var SelectThing = React.createClass({ render: function render() { // I would not like to add onClick handler to every button element // outside the RadioButtonGroup compo

我正在使用RadioButtonGroup组件,该组件类似于单选输入,但带有按钮:

如果组件的使用像这样简单就好了:

var SelectThing = React.createClass({
    render: function render() {
        // I would not like to add onClick handler to every button element
        // outside the RadioButtonGroup component
        return (
            <RadioButtonGroup onChange={this._onActiveChange}>
                <button>Thing 1</button>
                <button>Thing 2</button>
                <button>Thing 3</button>
            </RadioButtonGroup>
        )
    },

    _onActiveChange: function _onActiveChange(index) {
        console.log('You clicked button with index:', index);
    }
});
var SelectThing=React.createClass({
render:函数render(){
//我不想向每个按钮元素添加onClick处理程序
//在RadioButtonGroup组件外部
返回(
事情1
事情2
事情3
)
},
_onActiveChange:函数_onActiveChange(索引){
log('您单击了带有索引的按钮:',索引);
}
});
真正的问题是:我如何才能用React最优雅地做到这一点?(我发现了,但它并没有完全回答这个问题)

我的第一个直觉是在组件内部添加和删除onClick处理程序,以从组件的用户中删除锅炉板代码。我想到的另一个选择是给出例如
元素而不是按钮元素,并将它们放在RadioButtonGroup组件中创建的按钮元素中。我不太喜欢后者,因为与传递按钮相比,它在语义上没有多大意义

下面是组件(显然不工作)现在的样子:

// Radio input with buttons
// http://getbootstrap.com/javascript/#buttons-checkbox-radio
var RadioButtonGroup = React.createClass({
    getInitialState: function getInitialState() {
        return {
            active: this.props.active || 0
        };
    },

    componentWillMount: function componentWillMount() {
        var buttons = this.props.children;
        buttons[this.props.active].className += ' active';

        var self = this;
        buttons.forEach(function(button, index) {
            // How to dynamically set onclick handler for virtual dom
            // element created inside JSX?
            button.addEventListener('onClick', function(event) {
                self._onAnyButtonClick(index, event);
            }
        });
    },

    componentWillUnmount: function componentWillUnmount() {
        var buttons = this.props.children;

        buttons.forEach(function(button, index) {
            button.removeEventListener('onClick');
        });  
    },

    render: function render() {
        return (
            <div className="radio-button-group">
                {buttons}
            </div>
        )
    },

    _onAnyButtonClick: function _onAnyButtonClick(index, event) {
        this.setState({
            active: index
        });

        this.props.onChange(index);
    }
});
//带按钮的单选输入
// http://getbootstrap.com/javascript/#buttons-复选框收音机
var RadioButtonGroup=React.createClass({
getInitialState:函数getInitialState(){
返回{
活动:this.props.active | | 0
};
},
componentWillMount:函数componentWillMount(){
var buttons=this.props.children;
按钮[this.props.active].className+=“active”;
var self=这个;
按钮。forEach(功能(按钮、索引){
//如何为虚拟dom动态设置onclick处理程序
//在JSX中创建的元素?
addEventListener('onClick',函数(事件){
self.\u onanybutton单击(索引、事件);
}
});
},
componentWillUnmount:函数componentWillUnmount(){
var buttons=this.props.children;
按钮。forEach(功能(按钮、索引){
按钮。removeEventListener('onClick');
});  
},
render:函数render(){
返回(
{按钮}
)
},
_onAnyButtonClick:函数_onAnyButtonClick(索引、事件){
这是我的国家({
活动:索引
});
此.props.onChange(索引);
}
});

如果不想弄乱每个按钮上的单击处理程序,只需侦听容器上的单击。然后根据单击的子项更新状态

此外,使用React,最好将所有DOM内容保留在render函数中。在本例中,定义元素的类名

这是如何工作的:

var RadioButtonGroup = React.createClass({
    getInitialState: function getInitialState() {
        return {
            active: this.props.active || 0
        };
    },

    clickHandler: function clickHandler(e) {
        // Getting an array of DOM elements
        // Then finding which element was clicked
        var nodes = Array.prototype.slice.call( e.currentTarget.children );
        var index = nodes.indexOf( e.target );
        this.setState({ active: index });
    },

    render: function render() {
        var buttons = this.children.map(function(child, i) {
            if (i === this.state.active) child.props.className += ' active';
            return child;
        }, this);

        return (
            <div className="radio-button-group" onClick={ this.clickHandler }>
                { buttons }
            </div>
        )
    }
});
var RadioButtonGroup=React.createClass({
getInitialState:函数getInitialState(){
返回{
活动:this.props.active | | 0
};
},
clickHandler:函数clickHandler(e){
//获取DOM元素数组
//然后查找单击了哪个元素
var节点=Array.prototype.slice.call(e.currentTarget.children);
var索引=节点。索引of(e.target);
this.setState({active:index});
},
render:函数render(){
var buttons=this.children.map(函数(child,i){
如果(i==this.state.active)child.props.className+='active';
返回儿童;
},这个);
返回(
{按钮}
)
}
});
要获得这样的api(类似于
),我们需要使用cloneWithProps插件


测试1
测试2
测试3
所有这一切只需获取每个子级,添加一个单击处理程序,并有条件地向其添加一个“active”类名。您可以(并且应该)轻松地对其进行修改,以将active类名作为一个道具

var RadioButtonGroup=React.createClass({
render:function(){
返回{React.Children.map(this.props.Children,this.renderItem)}
},
renderItem:函数(按钮、索引){
返回React.cloneElement(按钮{
类名:this.props.value==索引“活动”:“,
onClick:function(){
此.props.onChange(索引);
}.绑定(此),
关键词:索引
});
}
});
如果您不想使用cloneWithProps,可以使用包装器div,但样式可能要复杂一些

renderItem:函数(按钮、索引){
返回React.createElement('div'{
类名:this.props.value==索引“活动”:“,
onClick:function(){
此.props.onChange(索引);
}.绑定(此),
关键词:索引
},按钮);
}
所有东西都使用索引的原因是,您正在传递不透明的react元素。没有干净的方法可以从这些按钮中获取任何数据,但我们确实知道它们的索引,因为我们使用react.Children.map对它们进行迭代。另一种api如下所示:

var SelectThing = React.createClass({
    render: function render() {
        // I would not like to add onClick handler to every button element
        // outside the RadioButtonGroup component
        return (
            <RadioButtonGroup onChange={this._onActiveChange}>
                <button>Thing 1</button>
                <button>Thing 2</button>
                <button>Thing 3</button>
            </RadioButtonGroup>
        )
    },

    _onActiveChange: function _onActiveChange(index) {
        console.log('You clicked button with index:', index);
    }
});


在这里,我们可以迭代this.props.options,将键传递给onChange回调,并将例如“test1”作为值prop。

这是我的代码。我不知道这是否是最好的方法,因为我在5小时前才开始使用react。但它工作正常

var LeftPane = React.createClass({
    getInitialState: function() {
        return {list:[{name:"Item 1",isactive:1},
                      {name:"Item 2",isactive:0},
                      {name:"Item 3",isactive:0},                     
                      {name:"Item 4",isactive:0},
                      {name:"Item 5",isactive:0}]};
    },
    clickHandler: function(index) {
        var current_list = this.state.list;
        current_list.map(function(record,i){
          if(record.isactive==1){
            if(i!=index){
              record.isactive =0;
            }else{
              return;
            }
          }else{
            if(i==index){
              record.isactive =1;
            }
          }
        });
        this.setState({data:current_list}); 
    },   
    render: function() {
        var active_item = "list-group-item active"
        var non_active_item ="list-group-item";
        var _this = this;
        return (              
          <div className="list-group">
            {this.state.list.map(function(record,i) {                          
                if(record.isactive==1){
                return <a className={active_item} onClick={_this.clickHandler.bind(null, i)}>{record.name}</a>
                }else{
                return <a className={non_active_item} onClick={_this.clickHandler.bind(null, i)}>{record.name}</a>
                }                  
            })}
          </div>
        </div>
        )
    }
});
var LeftPane=React.createClass({
getInitialState:函数(){
返回{list:[{name:“Item 1”,isactive:1},
{名称:“项目2”,i活动:0},
{名称:“项目3”,i活动:0},
{名称:“项目4”,i活动:0},
{名称:“项目5”,i活动:0}]};
},
clickHandler:函数(索引){
var current_list=this.state.list;
当前列表映射(功能(rec