Mixin 函数只在 render() 中有效
Mixin functions only work in render()
出于某种原因,我的代码中的 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 函数包含在另一个函数中以处理点击时 - 就像这样 - 一切都失败了,甚至 'test' 也没有在控制台中打印出来:
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>
);
}
});
编辑:
order
和 noOrder
函数如下所示:
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);
}
为了在 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.order
和 this.noOrder
返回的函数不再由 handleOrderClick
返回,而是立即执行。这应该会提供您想要的效果。
我已将您示例中的代码放入 jsfiddle 中,现在它似乎可以正常工作。我不得不将道具 'else' 更改为 'alt' 因为 'else' 是一个保留字。为了简单起见,我还直接将 mixin 应用于 class。我已经简化了 order
和 noOrder
函数,因为我无法访问 Order
对象,我们只对它们在正确的时间触发感兴趣。我还添加了第二个按钮,您可以单击它来翻转案例,以便呈现另一个按钮,从而使组件再次呈现。我添加了一个标签,显示上次按下按钮时调用了哪个函数。
作为参考,您可以找到有关绑定方法的更多信息here。
希望对你有帮助^_^
出于某种原因,我的代码中的 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 函数包含在另一个函数中以处理点击时 - 就像这样 - 一切都失败了,甚至 'test' 也没有在控制台中打印出来:
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>
);
}
});
编辑:
order
和 noOrder
函数如下所示:
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);
}
为了在 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.order
和 this.noOrder
返回的函数不再由 handleOrderClick
返回,而是立即执行。这应该会提供您想要的效果。
我已将您示例中的代码放入 jsfiddle 中,现在它似乎可以正常工作。我不得不将道具 'else' 更改为 'alt' 因为 'else' 是一个保留字。为了简单起见,我还直接将 mixin 应用于 class。我已经简化了 order
和 noOrder
函数,因为我无法访问 Order
对象,我们只对它们在正确的时间触发感兴趣。我还添加了第二个按钮,您可以单击它来翻转案例,以便呈现另一个按钮,从而使组件再次呈现。我添加了一个标签,显示上次按下按钮时调用了哪个函数。
作为参考,您可以找到有关绑定方法的更多信息here。
希望对你有帮助^_^