Nic*_*vda 8 javascript reactjs
各位开发者!
感谢Egghead的教程,我一直在深入研究Flux/React.虽然我听说React正在移动,但是在遵循上述教程的同时,我在React库中遇到了一些变化.
到目前为止,我已经能够解决所有问题.现在,我遇到了关于商店的砖墙.正如教程所述,我正在制作一个购物车,用户可以在其中添加商品.没那么复杂.实际添加有效,但不会触发重新渲染.以下代码给出了添加的错误(完整代码也将在下面列出):
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
Run Code Online (Sandbox Code Playgroud)
这导致Uncaught TypeError:listener必须是一个函数.回调参数未定义(因此问题出在哪里).但是,因为我不仅仅是新的React的工作方式,我在查找问题方面遇到了麻烦.以下代码段是教程中的Store:
var AppStore = assign(EventEmitter.prototype, {
emitChange: function() {
this.emit(CHANGE_EVENT);
},
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback) {
this.removeChangeListener(CHANGE_EVENT, callback);
},
getCart: function() {
return _cartItems;
},
getCatalog: function() {
return _catalog;
},
getCartTotals: function() {
return _cartTotals();
},
dispatcherIndex: AppDispatcher.register(function (payload) {
var action = payload.action;
switch(action.actionType) {
case AppConstants.ADD_ITEM:
_addItem(payload.action.item);
break;
case AppConstants.REMOVE_ITEM:
_removeItem(payload.action.index);
break;
case AppConstants.INCREASE_ITEM:
_increaseItem(payload.action.index);
break;
case AppConstants.DECREASE_ITEM:
_decreaseItem(payload.action.index);
break;
}
AppStore.emitChange();
return true;
})
});
Run Code Online (Sandbox Code Playgroud)
请注意,这是来自Egghead.io教程的代码,我不是所有者(如果他们希望我将删除所述代码).
如果需要更多代码或解释,我将很乐意帮忙!
谢谢人们:)
编辑1:应该听取改变的组件,但不是:
var Cart = React.createClass({
getInitialState: function() {
return cartItems();
},
componentWillMount: function() {
debugger;
AppStore.addChangeListener(this.onChange);
},
componentDidMount: function() {
debugger;
AppStore.addChangeListener(this.handleChange);
},
handleChange: function() {
debugger;
this.forceUpdate();
},
_onChange: function() {
debugger;
this.setState(cartItems());
},
render: function() {
var total = 0;
var items = this.state.items.map(function (item, i) {
var subtotal = item.cost * item.qty;
total +=subtotal;
return (
<tr key={i}>
<td><RemoveFromCart index={i} /></td>
<td>{item.title}</td>
<td>{item.qty}</td>
<td>
<Increase index={i} />
<Decrease index={i} />
</td>
<td>${subtotal}</td>
</tr>
);
});
return (
<table className="table table-hover">
<thead>
<tr>
<th></th>
<th>Item</th>
<th>Qty</th>
<th></th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
{items}
</tbody>
<tfoot>
<tr>
<td colSpan="4" className="text-right">Total</td>
<td>${total}</td>
</tr>
</tfoot>
</table>
);
}
});
Run Code Online (Sandbox Code Playgroud)
对我来说,听起来你已经解决了这个模式的大部分内容,但你有点困惑。您需要包括最后一步,这实际上是为您的组件订阅商店推出的事件。
this.emit(CHANGE_EVENT);
Run Code Online (Sandbox Code Playgroud)
这只会将一些东西推出去。如果没有人在监听,那么什么都不会改变,因此在您的组件中,您需要实际监听此事件。
对于一个组件来说,它可能看起来像这样:
React.createClass({
componentDidMount: function() {
// Called after react has rendered the HTML in the DOM.
AppStore.addChangeListener(this.handleChange);
},
render: function() {
return <div>{AppStore.someData}</div>
},
handleChange: function() {
this.forceUpdate();
}
});
Run Code Online (Sandbox Code Playgroud)
注意:this.emit不应该打电话addChangeListener。它应该触发您使用该方法订阅的回调addChangeListener。
潜在的改进
AppStore,但并非所有组件都会关心所有数据。例如,如果您有一个Name呈现用户名的组件,那么他们只关心NAME_CHANGE_EVENT. 他们不想每次发生小事就重新渲染。这是 React 不必要的处理,尽管 React 会推测没有任何变化并且不会更新 DOM。| 归档时间: |
|
| 查看次数: |
1756 次 |
| 最近记录: |