我正在玩一些反应来构建一个"添加到购物车按钮"。这是我的代码。
var ProductPurchase = React.createClass({
handleSubmit: function(e){
e.preventDefault();
$.ajax({
url: "/cart/add.js",
method: "post",
dataType: "json",
data: {
"id": this.props.variantId,
"quantity": this.props.quantity,
},
success: function(data) {
// emit cart added event
}.bind(this),
error: function(xhr, status, err) {
// emit error event (cart added)
}.bind(this)
});
},
getDefaultProps: function(){
return {
quantity: 1,
variantId: 231634908,
buttonText: "Add to cart"
}
},
render: function() {
return (
<div className="productPurchase">
<form action="/cart/add" method="post" enctype="multipart/form-data" onSubmit={this.handleSubmit}>
<input type="hidden" name="quantity" value={ this.props.quantity } />
<input type="hidden" name="id" value={ this.props.variantId } />
<button type="submit">{this.props.buttonText}</button>
</form>
</div>
);
}
});
我很好奇的是这个ajax处理程序。我非常确定反应的重点是组件之间的互操作性,除非我不知道将这些事件引向何处。我可以想象一些不同的组件,如购物车计数指示器,如果成功或错误提醒,如果失败,但我不知道如何利用这些。这是flux's dispatchers的全部内容吗?
答案 0 :(得分:17)
是的,这肯定是Flux调度员的一部分 - 或者您想要使用的任何事件发射器。
在你走这条路之前,很容易将事件处理程序作为道具传递而不使用Flux或自定义事件发射器 - 就像使用onSubmit
,onClick
等处理程序一样普通的DOM元素。然后让父母处理设置状态,并可能将其传达给其他孩子(通过道具)。
因此,在这种情况下,想象一下处理事件的父组件:
var RootComponent = React.createClass({
handleCartAdded: function(cart) {
console.log('Got a new cart: ' + cart);
}
handleError: function(err) {
console.error(err)
}
render: function() {
return (
<ProductPurchase onCartAdded={this.handleCartAdded} onError={this.handleError} />
)
}
})
然后,ProductPurchase
组件的相关部分将是:
success: function(data) {
this.props.onCartAdded(data)
}.bind(this),
error: function(xhr, status, err) {
this.props.onError(err)
}.bind(this)
更复杂的例子是将结果传递给另一个子组件 - 但是,再次将其留给父组件来管理它:
var RootComponent = React.createClass({
handleCartAdded: function(cart) {
this.setState({cart: cart})
}
handleError: function(err) {
console.error(err)
}
render: function() {
return (
<div>
<ProductPurchase onCartAdded={this.handleCartAdded} onError={this.handleError} />
<CartSummary cart={this.state.cart} />
</div>
)
}
})
这样,组件彼此分离 - 数据/功能只能通过明确的合同(道具)传递。
这种简单的事件处理方式更明确,更容易调试 - 所以如果你的应用变得非常复杂和/或你需要很多组件,我真的只会求助于Flux风格的架构以复杂的方式相互沟通。
答案 1 :(得分:5)
Flux用于解耦编程结构(包括AJAX调用)。
以下是Flux Docs
的图表Flux架构中的
Dispatcher 始终保持在全局范围内。因此,调度程序涉及的任何操作始终发生在全局范围内。此外,调度程序和事件系统略有不同,事件系统始终注册绑定到特定事件的回调,但在调度程序的情况下,所有回调都绑定到所有事件。
如何使用Dispatcher? (不使用Stores和ActionCreators的简化方法)
如果应用程序的其他部分受到此AJAX调用的影响,那么您不应该从此组件进行此AJAX调用,而是将AJAX调用移动到新文件和函数中。例如,使用CommonJS,
// CartApiUtils.js
module.exports = {
addToCart: function(item){
// AJAX call
}
}
使用Flux&#39; Dispatcher class
创建AppDispatcher(在整个应用程序中很常见)var appDispatcher = new Dispatcher();
在addToCart()函数中,成功的AJAX响应,使用AppDispatcher调度事件:
appDispatcher.dispatch({
actionType: 'cart.newItemAdded',
data: dataFromAjax
});
在您的应用中,无论您想在何处使用此活动,都可以向调度员注册一个功能。
appDispatcher.register(function(payload){
if(payload.actionType === 'cart.newItemAdded'){
// payload.data contains the data
}
});
这是一种简化的方法。在更规范化的结构和更大的应用程序中,您应该使用Stores(类似于MVC的Model层,但不完全相同)和ActionCreator,其中视图层上的任何交互都是用户的操作以及AJAX调用的任何响应也成为服务器的一个动作。
Thumb规则是,必须从商店填充(或更新)视图,并且必须在Dispatcher事件上更新商店。
答案 2 :(得分:2)
如何使用npm的“ react-global-events ”?
答案 3 :(得分:0)
Flux 是维护模式,因此如果您打算构建一个生产就绪的应用程序,我不建议您使用它。替代方案是 Redux 或 MobX,不过我总是使用 React's builtin Context 来处理全局状态 - 易于实现并且工作起来很迷人。