【问题标题】:Mixin functions only work in render()Mixin 函数仅适用于 render()
【发布时间】:2016-01-19 11:27:39
【问题描述】:

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

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

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 函数包含在另一个函数中来处理点击时 - 像这样 - 一切都失败了,甚至“测试”也没有打印在控制台中:

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

【问题讨论】:

    标签: javascript reactjs mixins


    【解决方案1】:

    为了在handleOrderClick 中使用this.setState,您必须在渲染方法中使用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的更多信息。

    希望对你有所帮助^_^

    【讨论】:

    • 感谢您的帮助!它让我朝着正确的方向前进,但我仍在努力。如果我按照您的建议添加return(顺便说一句,这是个好主意,我自己应该想到的),那么这些函数会在点击和渲染时触发。为了反击渲染时触发,我应该添加bind(),但如果我也添加它,那么我会回到第一方,并且根本不会触发函数。我还用ordernoOrder 函数更新了原始问题。
    • 我已经根据您的编辑更新了我的答案。如果您还有任何问题,请告诉我 =)
    • 只要我不在点击处理程序中添加this.setState({});,它就可以很好地工作。这就是我说它在渲染和点击时触发的意思。对于console.log(),这是可以接受的,但对于this.setState({}),它会导致反应错误,即您无法修改render() 中的状态。我怎样才能修改点击状态?
    • 抱歉,我误解了 =) 如果您想在使用 setState 时使用 handleOrderClick,我所知道的最简洁的方法是在您的渲染方法中使用绑定。我已经用更新的方法和 jsfiddle 编辑了我的答案,希望这次我解决了它^_^
    • 哇,新东西。 :) 难怪我遇到了麻烦,我以前没有使用过(甚至见过!)那种语法。不过非常感谢你,我整理好了,为你鼓掌!
    猜你喜欢
    • 2017-03-27
    • 2021-08-10
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 2017-01-20
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多