Dispatching Redux

When I think of redux this is what comes to mind:

And that’s not because I was ready to have my brain checked when starting to learn React/Redux 🙂

I am writing this post to explain to you how I think of React/Redux, and how it helped me better understand it, and I hope it can help you too!

This is not a detailed walk through, for tutorials on React/Redux I can recommend:

Among many of the fabulous resources out there people have taken the time out to help us understand this framework.

So now back to my ambulances…

If we want to have a function that will not be called on load, but rather upon an action — for example an onClick function, we cannot put the () after the function as that will call it as soon as the page loads it. We can’t put the function without the () because that will just show what’s contained in the function instead of ever running it. We need to somehow bind that function to the event so it can be triggered exactly when we want it to with the applicable event/data.

In redux to accomplish this we  dispatch the function. Here is a code example from my repo – https://github.com/mxdavis/timer-billing-client/

import {removeTask} from '../../redux/actions/tasks/tasks'

....

  handleDelete = event => {
    event.preventDefault();
    ...
    this.props.removeTask(this.state)
}

render(){
  return(
     ...
      <div className="uk-width-2-2 uk-text-center">
         <button
           onClick={this.handleDelete} 
           type="delete"
           value="Delete Task"
           >X</button>
        </div>
      ...
   )
}

...

const mapDispatchToProps = dispatch => {
  return bindActionCreators(
    { fetchClients, addTask, removeTask }, dispatch);
};

export default connect(mapStateToProps, mapDispatchToProps)(AddTask);

 

Here we have the a delete button that dispatches an action removeTask onClick. Since I use mapDispatchToProps I do not need to put dispatch(removeTask(this.state)) instead if I use this.props.removeTask(this.state), the mapDispatchToProps already bound dispatch to removeTask and I can access it through props.

This function is an action and looks like so:

export function removeTask(task){
  return {
    type: 'REMOVE_UNBILLED_TASK',
    task
  }
}

The file was able to find it, because I had imported it previously (see the top line of the previous code snippet). I could have had this function locally in the folder, but to keep the file from getting too heavy I put it in an actions folder.

Now this action is being dispatched from the emergency call center to all the medics who have their radios always on waiting to accept the signal. And the medic in the right area that fits the type needed responds to the action and does what it is told to do.

This is where the reducers come in.

The reducers are set up in the store (normally through a combinedReducers, as there are frequently more than one reducer). Here is an example of my file that sets up redux store:

import {createStore, applyMiddleware, combineReducers } from 'redux'
import thunk from 'redux-thunk'

import clients from '../reducers/clients/clients'
import tasks from '../reducers/tasks/tasks'
import fetchingData from '../reducers/fetchingData'

const reducers = combineReducers({
  tasks, clients, fetchingData
})

const middleware = [thunk]

export default createStore(
  reducers, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(), 
  applyMiddleware(...middleware)
)

 

The combineReducers is combining all my reducers, and we pass this into createStore.

What this does is give the reducers each their own radio that is turned on and ready to listen when an action is being called just like when a person starts working as a medic he is given a radio that he needs to leave on and always listen to.

If you put a debugger in a reducer, you will see that it is called each time the page/app renders, even if the action never called that particular one, or if even any action is called at all.

Reducers are case statements looking for a string that matches the action.type that the action sent out.

With each state update, it checks to see if the action.type has been called, and if it does it will run the code inside.

Back to our analogy, when a medic’s radio hits based on certain criteria, he will receive the follow up instructions, while everyone else’s radio will stay silent as they do not need to be disturbed yet. If we had all our medics responding to every call they would be running all over the place, and not actually showing up to anyone on time and in an efficient manner. And not to mention, they’d probably all quit, and work for a more efficient team that knew how to alert only medics in the vicinity or medics with the equipment necessary for the call…

Here is what my reducer looks like that will match the string ‘REMOVE_UNBILLED_TASK’:

export default function tasks(state = {
    unbilled_tasks: [], 
    billed_tasks: []
}, action) {
  switch (action.type) {
  ...
    case 'REMOVE_UNBILLED_TASK':
      const tasksWithoutDeletedTask = state.unbilled_tasks.filter(t => t.task_id !== action.task.task_id)
      return Object.assign({}, state, {unbilled_tasks: tasksWithoutDeletedTask})
    default:
      return state;
  }
};

 

Always remember that since every reducer function gets called with each render we need to include a default option in our case statement that returns the current state, so that we do not end up with an empty state each time the page updates.

Keep this in mind when creating your reducers.

So to sum up my analogy, our medics/reducers always have their radios on waiting to be called, and this we set up by creating the redux store with our combinedReducers (unless we have only one reducer then we just put that one reducer in the store). The functions from the component dispatch actions only when they are triggered, and not upon load of the page (like onClick, or onChange..), which our component (medical center) sends the action.types to the correct (medic) reducer (instead of running all actions on load, and sending all medics on every call which would be extremely inefficient and time consuming!).

I hope I was able to help some people better understand the redux cycle. This was my first react/redux project and this concept really helped getting me started.

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright Loving to Code 2025
Tech Nerd theme designed by Siteturner