Mixin函数仅适用于render()

时间:2016-01-19 11:27:40

标签: javascript reactjs mixins

出于某种原因,我的代码中的mixin函数似乎只能在render()函数中正常工作。可能是因为我没有在render()之外以正确的方式调用它们,但它不应该完全相同吗?

这样一切正常(但我不能坚持这个,因为我必须添加一些额外的东西来点击处理,同时不改变混音):

var Row = React.createClass({
    mixins: [someMixin]
    },

    render: function () {
        var clickHandler = null;
        var btn = null;

        if (firstCase) {
            clickHandler = this.order(this.props.name, this.props.else);
            btn = (<a href="" onClick={clickHandler}>Order</a>);
        } else if (secondCase) {
            clickHandler = this.noOrder(this.props.name, this.props.else);
            btn = (<a href="" onClick={clickHandler}>No order</a>);
        }
        return (
            <div>
                {btn}
            </div>
        );
    }
});

但是,当我做了显而易见的事情并将mixin函数包含在另一个函数中来处理点击时 - 就像这样 - 一切都失败了,甚至测试了#39;未在控制台中打印:

var Row = React.createClass({
    mixins: [someMixin]
    },

    handleOrderClick(type) {
        console.log('test');
        if (type == 'order') {
            this.order(this.props.name, this.props.else);
        } else if (type == 'no-order') {
            this.noOrder(this.props.name, this.props.else);
        }
    },

    render: function () {
        var clickHandler = null;
        var btn = null;

        if (firstCase) {
            clickHandler = this.handleOrderClick('order');
            btn = (<a href="" onClick={clickHandler}>Order</a>);
        } else if (secondCase) {
            clickHandler = this.handleOrderClick('no-order');
            btn = (<a href="" onClick={clickHandler}>No order</a>);
        }
        return (
            <div>
                {btn}
            </div>
        );
    }
});

编辑: ordernoOrder函数如下所示:

order: function (name, else) {
    return function (event) {
        event.preventDefault();

        var term = name + '&&¤%' + else;
        Order.order(name, else, period, function (data) {

            if (term === (global || window).MAIN_NAME + '.' + (global || window).MAIN) {
                $(window).trigger('Name:update');
            }
        }.bind(this));
    }.bind(this);
},

noOrder: function (name, else) {
    return function (event) {
        event.preventDefault();

        if (!this.state.transferModalOpen) {
            this.toggleTransferModal();
        }
    }.bind(this);
}

1 个答案:

答案 0 :(得分:0)

要在this.setState中使用handleOrderClick,您必须在渲染方法中使用bind方法。因此handleOrderClick将成为:

handleOrderClick(type, event) {
    this.setState({foo: 'bar'});
    if (type == 'order') {
        this.order(this.props.name, this.props.else)(event);
    } else if (type == 'no-order') {
        this.noOrder(this.props.name, this.props.else)(event);
    }
},

并且您的渲染方法变为:

render: function () {
    var clickHandler = null;
    var btn = null;

    if (firstCase) {
        clickHandler = this.handleOrderClick.bind(this, 'order');
        btn = (<a href="" onClick={clickHandler}>Order</a>);
    } else if (secondCase) {
        clickHandler = this.handleOrderClick(this, 'no-order');
        btn = (<a href="" onClick={clickHandler}>No order</a>);
    }
    return (
        <div>
            {btn}
        </div>
    );
}

您会注意到this.orderthis.noOrder返回的函数不再由handleOrderClick返回,而是立即执行。这应该提供你想要的效果。

我已将您示例中的代码放入jsfiddle,现在它似乎正常运行。我不得不将道具'else'更改为'alt',因为'else'是一个保留字。为了简单起见,我还直接将mixin应用到了类中。我已经简化了ordernoOrder函数,因为我无法访问Order对象,我们只对它们在正确的时间触发感兴趣。我还添加了第二个按钮,您可以单击以翻转案例,以便渲染另一个按钮,从而导致组件再次渲染。我添加了一个标签,显示上次按下按钮时调用了哪个功能。

供参考,您可以找到有关绑定方法here的更多信息。

希望这有助于^ _ ^