1

I am facing some issue while using Dispatcher in ReactJS. So, I try to remove this dispatcher from the store and still store works well. Store properly hold my data and change event works well.

Now I am bit confusing to use dispatcher in our application.

Here is the code

MenuList is my component in which I call MenuStore.getMenuFromAPI() and after I also added onChange event of MenuStore.

class MenuList extends React.Component{

  constructor(){
    super();
    this.state = {open:false, menuList:"",numbering:-1}
  }

  componentWillMount(){
    var that = this;
    MenuStore.getMenuFromAPI();
    MenuStore.on("change", ()=> {
      that.setState({menuList:MenuStore.getMenu()});
    })
  }

  componentWillReceiveProps(nextProps){
    if(nextProps.show!=this.props.show){
      this.setState({open:nextProps.show});
    }
  }

  render(){
    const { classes } = this.props;

    return (

      <div>My MEnu</div>
    )
  }
}

MenuStore

class MenuStore extends EventEmitter {
  constructor() {
    super();
    this.menu = null;
  }

  getMenu(){
    return this.menu;
  }

  getMenuFromAPI(){
    var that = this;
    $.ajax({
      type: "POST",
      url: LinkConstants.GETMENU,
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
      },
      data: "",
      dataType :"json",
      success: function(response) {
        that.menu =response;
        that.emit("change");
      }.bind(this),
      error: function(xhr, status, err) {
        console.log(err);
      }.bind(this)
    });
  }

  // handleAction(action) {
  //   switch (action.type) {
  //     case ActionTypes.MENU: {
  //       this.getMenuFromAPI();
  //       break;
  //     }
  //   }
  // }

}

const menuStore = new MenuStore;
//Dispatcher.register(menuStore.handleAction.bind(menuStore));
export default menuStore;

As you can see I commented out Dispatcher.register line and handleAction function.

Above code works properly fine but I wanted to know why to use Dispatcher over here ?

If I want to just store my data in the MenuStore and get it back from MenuStore on any of the component in the application. So it is necessary to use dispatchers and action or to just work with stores only.

Please clarify my doubts with proper example or case scenario (if possible) when to use dispatchers and action or when to work with stores only.

bignose
  • 30,281
  • 14
  • 77
  • 110
Kushal Jain
  • 3,029
  • 5
  • 31
  • 48

1 Answers1

4

In your example your are not using Redux at all, you've just created a class that is used as a simple storage for the fetched data but your are not using any of Redux capabilities.

Redux is all about one store which is just a plain object which represents your application state tree. In order to change this state you dispatch actions. Actions are just simple objects which describe what happened. Each action has a type field which describes the action. Actions are treated by reducers which are functions that gets the current state and the dispatched action and decide on the next state of the application. This is Redux in few sentences.

Redux store has a method named dispatch which is used to dispatch actions. As mentioned in Redux documentation, this is the only way to trigger a state change.

Lets say we have a TODO list application. Our store may be represented as an array of strings (todo items).

To add a new item to the list we will define a simple action:

const addItemAction = (item = '') => ({
    type: 'ADD_ITEM',
    data: item,
});

Dispatching this action can be done from within one of your component's methods which will be attached to some keyboard/mouse event:

class TodoList extends React.Component {
    ...
    // addNewItem is called with a value from a text field
    addNewItem(item) {
        store.dispatch(addItemAction(item));
    }
    ...
}

As I mentioned above, state is changed by a reducer function. The reducer decides if to change the state and how to change it. If dispatched action shouldn't change the state it can just return the received state:

function todoReducer(state = [], action) {
    switch(action.type) {
        case 'ADD_ITEM':
            return [...state, action.data];
        break;
        default:
            return state;
    }
}

Reducer is passed to createStore method:

import { createStore } from 'redux'    
const store = createStore(todoReducer);

In the TodoList component you can subscribe to the store using store.subscribe method which accepts a callback function that will be called each time the store state changes. When detecting a change you can call setState of your component to set the list on the component state and to cause the component to rerender:

class TodoList extends React.Component {
    ....
    componentDidMount() {
        this.storeSubscription = store.subscribe((state) => {
            // For the example I'm just setting the state (list of todos) 
            // without checking if it changed or not
            this.setState({
                todos: state,
            });
        });
    }

    render() {
        return this.state.todos.map(todo => <div>{todo}</div>);
    }
    ....
}

This is an almost complete example of using Redux. We used action to describe an event in our application, we used the store's dispatch method to dispatch the action to the store, Redux will invoke the reducer when it gets new actions, the reducer computes the new state and our component detects the change by using the store's subscribe method.

There are more things to consider and to take care of in a more complex application. You will probably have a more complex state tree so you will need additional reducers to take care of computing the state. Additionally in some step you would need to consider working with some helpers to reduce overhead of subscribing to state change and detecting changes.

In a more complex application you would probably connect your component to the store by a binding library such as react-redux so your component will receive the relevant parts of the store by props which will save the overhead of subscribing to the store changes and deciding on when to rerender the component.

I would recommend watching "Getting started with Redux" by Dan Abramov to get some more understanding of what is Redux and how to work with it. Getting started with Redux

bignose
  • 30,281
  • 14
  • 77
  • 110
Matan Hafuta
  • 605
  • 6
  • 14