Function ReactJS直接访问父函数onClick引用无限循环

Function ReactJS直接访问父函数onClick引用无限循环,function,loops,reactjs,prop,Function,Loops,Reactjs,Prop,今天我开始用React构建,但有些结果出乎意料。所以我想解释一下。我有以下组件: var QuestionItem = React.createClass({ sendVote: function(e) { $(e.target).hasClass('up') ? this.props.onVoteUpdate(this.props.id, 'up') : this.props.onVoteUpdate(this.props

今天我开始用React构建,但有些结果出乎意料。所以我想解释一下。我有以下组件:

var QuestionItem = React.createClass({
    sendVote: function(e) {
        $(e.target).hasClass('up')
            ? this.props.onVoteUpdate(this.props.id, 'up')
            : this.props.onVoteUpdate(this.props.id, 'down');
    },


    render: function() {
        return (
            <li data-up={this.props.up} data-down={this.props.down}>
                <div className="votes">
                    <span className="up" onClick={this.sendVote}>+</span>
                    <span className="down" onClick={this.sendVote}>-</span>
                </div>
            </li>
        );
    }
});
它以控制台日志的无限循环结束

onVoteUpdate: function(question, state) {
    console.log(question);
    console.log(state);
});

这是不可能的,还是我做错了什么?

看看JSX是如何编译的可能会有所帮助:

<div className="votes">
    <span onClick={this.props.onVoteUpdate(this.props.id, 'up')}>+</span>
    <span onClick={this.props.onVoteUpdate(this.props.id, 'down')}>-</span>
</div>
如您所见,您并没有将
onClick
处理程序分配给您的方法,而是将其分配给该方法的返回值,因为您实际上是在渲染期间调用它

我建议将这种行为分为两种方法:

var QuestionItem = React.createClass({
    sendUpVote: function () {
        this.props.onVoteUpdate(this.props.id, 'up');
    },

    sendDownVote: function () {
        this.props.onVoteUpdate(this.props.id, 'down');
    },

    render: function() {
        return (
            <li data-up={this.props.up} data-down={this.props.down}>
                <div className="votes">
                    <span className="up" onClick={this.sendUpVote}>+</span>
                    <span className="down" onClick={this.sendDownVote}>-</span>
                </div>
            </li>
        );
    }
});
var QuestionItem=React.createClass({
sendUpVote:函数(){
this.props.onVoteUpdate(this.props.id,'up');
},
sendDownVote:函数(){
this.props.onVoteUpdate(this.props.id,'down');
},
render:function(){
返回(
  • + -
  • ); } });

    尽管可能会有更多的代码,但在阅读代码时会更清楚应该发生什么。

    了解JSX的编译方式可能会有所帮助:

    <div className="votes">
        <span onClick={this.props.onVoteUpdate(this.props.id, 'up')}>+</span>
        <span onClick={this.props.onVoteUpdate(this.props.id, 'down')}>-</span>
    </div>
    
    如您所见,您并没有将
    onClick
    处理程序分配给您的方法,而是将其分配给该方法的返回值,因为您实际上是在渲染期间调用它

    我建议将这种行为分为两种方法:

    var QuestionItem = React.createClass({
        sendUpVote: function () {
            this.props.onVoteUpdate(this.props.id, 'up');
        },
    
        sendDownVote: function () {
            this.props.onVoteUpdate(this.props.id, 'down');
        },
    
        render: function() {
            return (
                <li data-up={this.props.up} data-down={this.props.down}>
                    <div className="votes">
                        <span className="up" onClick={this.sendUpVote}>+</span>
                        <span className="down" onClick={this.sendDownVote}>-</span>
                    </div>
                </li>
            );
        }
    });
    
    var QuestionItem=React.createClass({
    sendUpVote:函数(){
    this.props.onVoteUpdate(this.props.id,'up');
    },
    sendDownVote:函数(){
    this.props.onVoteUpdate(this.props.id,'down');
    },
    render:function(){
    返回(
    
  • + -
  • ); } });

    尽管可能会有更多的代码,但在阅读代码时会更加清楚应该发生什么。

    事实上,我昨天在同样的问题上花了很长时间

    所发生的事情是,您正在调用
    this.sendVote
    当您将其分配给
    onClick
    事件时,这会导致无限循环,因为每次渲染时,它都会重新渲染,因为this.sendVote上的状态已更改,等等

    您希望做的是将
    this.sendVote
    绑定到
    onClick
    事件

    这就是你想要的:

    <span className="up" onClick={this.sendVote.bind(this)}>+</span>
    <span className="down" onClick={this.sendVote.bind(this)}>-</span>
    
    +
    -
    

    这样,你就不是在呼叫This.sendVote,而是在告诉“嘿!每次我点击This
    我都想呼叫This.sendVote”

    我昨天在同样的问题上度过了一段美好的时光

    所发生的事情是,您正在调用
    this.sendVote
    当您将其分配给
    onClick
    事件时,这会导致无限循环,因为每次渲染时,它都会重新渲染,因为this.sendVote上的状态已更改,等等

    您希望做的是将
    this.sendVote
    绑定到
    onClick
    事件

    这就是你想要的:

    <span className="up" onClick={this.sendVote.bind(this)}>+</span>
    <span className="down" onClick={this.sendVote.bind(this)}>-</span>
    
    +
    -
    
    这样,您就不会调用
    This.sendVote
    ,而是告诉“嘿!每次我单击This
    我都想调用
    This.sendVote

    
    +
    -
    
    render:function(){
    返回(
    
  • 这个.sendVote}>+ 这个.sendVote}>-
  • ); }
    }))

    这可能有效

    
    +
    -
    
    render:function(){
    返回(
    
  • 这个.sendVote}>+ 这个.sendVote}>-
  • ); }
    }))

    这可能有用

    render: function() {
        return (
            <li data-up={this.props.up} data-down={this.props.down}>
                <div className="votes">
                    <span className="up" onClick={()=>this.sendVote}>+</span>
                    <span className="down" onClick={()=>this.sendVote}>-</span>
                </div>
            </li>
        );
    }