Flux has three main parts.
- Action
- Dispatcher
- Store
Component
import React from 'react'; import checkoutActions from "../actions/checkout-action"; import checkoutStore from "../store/checkout-store"; class CartElements extends React.Component{ constructor(){ super() this.state = { currentCart : checkoutStore.getCart() } } componentDidMount(){ checkoutStore.addListener(this.updateCartNumber) }; updateCartNumber = () => { this.setState({ currentCart: checkoutStore.getCart() }) }; updateCart = () => { checkoutActions.addCart(parseInt(this.refs.cartNumber.value)) }; gotoCheckout = () => { window.location.href +="?products=[1,2,3]" }; render(){ var checkoutButton = ""; if(this.state.currentCart > 0){ checkoutButton = <a className="button" href="/welcome/checkout?products=[1,2,3,4]">CheckOut</a>; } return( <div> <div className="input-group"> <input type="number" ref="cartNumber"/> </div> <button className="button success" onClick={this.updateCart}>Add to Cart</button> {checkoutButton} </div> ) } } export default CartElements
Action File
import dispatcher from "../dispatcher"; import constants from "../const/store-const"; var checkoutActions = { addCart: function(data){ dispatcher.dispatch({ actionType: constants.ADD_CART, data: data }) } } export default checkoutActions;In this Action, I have an addCart method which dispatches item quantity along with a constant called ‘ADD_CART’ which is used to distinguish it on Store. Dispatcher is a simple file which uses Facebook dispatcher Object Assign is a NPM module where you can combine two objects and return source object, For example var birds = {bird:”Pigeon”} var animals = {animal:”Dog”} assign(birds, animals) => {bird:”Pigeon”, animal:”Dog”} We have a Store called checkStore, for which we have 5 methods. First 2 of them are custom methods, addCart and getCart. When we call Addcart, it increases the quantity and getCart to retrieve the latest value. Besides we have 3 required methods
- emitChange
- addListener
- removeListener
import dispatcher from '../dispatcher.js'; import EventEmitter from 'events'; import assign from 'object-assign'; var CHANGE_EVENT = 'change'; var EventEmitterEvent = EventEmitter.EventEmitter var _number = 0; var checkoutStore = assign({}, EventEmitterEvent.prototype, { addCart: function(number){ return _number = _number + number; }, getCart: function(){ return _number; }, emitChange: function(){ this.emit(CHANGE_EVENT) }, addListener: function(callback){ this.on(CHANGE_EVENT, callback) }, removeListner: function(callback){ this.removeListner(CHANGE_EVENT, callback) } }); dispatcher.register((action)=>{ switch (action.actionType){ case 'ADD_CART': console.log("hello") checkoutStore.addCart(action.data) checkoutStore.emitChange() break; } }) export default checkoutStore;AddListener adds EventListner. We can use this to bind events to components. RemoveListener is used to remove listeners when we unmounts some components. EmitChange is used to update or invoke store after some actions. The store also has a dispatcher, where we register dispatcher, and in action, we dispatch data to stores. All data which passes from action is available in action argument, the switch uses check actionType, we already pass a constant from action to distinguish various types, like CREATE, EDIT, DELETE, and here we have ADD_CART, so only particular block works. In this case, we have only one condition inside switch block and condition with ADD_CART will work. Inside this condition we call add_cart store method and pass quantity after which we can emitchange. So, this store will invoke and all components which are connected will notify. Now we can move to a header component. There is a component called CartIconOnTopBar, in componentDidMount.I have attached a Store listener, ‘checkOutStore.addListener(callback)’ with a callback function, in this callback function, I again called stores getCart function to get latest items quantity.
class CartIconOnTopBar extends React.Component{ constructor(){ super() this.state = { cartItemCount: checkoutStore.getCart() } } componentDidMount(){ checkoutStore.addListener(this.updateCart) }; updateCart = () => { this.setState({ cartItemCount: checkoutStore.getCart() }) }; openClassModal = () => { }; render(){ return( <li> <a href="#" onClick={this.openCartModal} className="cart-element"> <i className="fi-shopping-cart"></i> <span className="cart-count"> {this.state.cartItemCount} </span> </a> </li> ) } }When we click on button, it passes data to action and through dispatcher it reaches store and it invokes store and all components which connected to this store will notify and it run callback functions and then we can update our data’s. In this application for a demonstration you can add as many actions and store. This is only a basics of flux, there are more in flux, also, flux has some alternatives like redux.]]>
Hi I am not able to find source code for this flux example on git hub. Can you please share link from where I can download it. Thanks, Suresh