Reacting to Redux

Yes that’s my joke. Yes this is another article about differentiating redux and react.

Photo by Oskar Yildiz on Unsplash

As the last module of my bootcamp, I envisioned my final project to involve the ultimate battle between my general anxiety disorder and my burnout. Instead, the true battle ended up being my confusion between react and redux.

To my surprise, I genuinely enjoy react. As much as I struggled for the duration of the bootcamp, especially with javascript, I was excited at prospect of working in react for my final project. I would’ve been happy if the whole project was just react but alas, it was not. I felt a cloud of vagueness hang over my head when redux was introduced. The confusion lingered once it was time to integrate redux into my project. I felt my mind draw a blank at the prospect of this undertaking so I decided to review the initial differences of react and redux before I started coding.

React: a framework that has access to a library written entirely in JSX and other dependencies
-JSX is an extension of vanilla JavaScript with a syntax very similar to HTML
-parts of JSX are separated by components (using separation of concerns)
-the sum of these components create a web application
-React state is stored locally within a component, meaning it’s state cannot be accessed unless passed down through props
-props are passed down from the parent component to it’s children (from top to bottom)
-Other dependencies include:
Babel: a source to source translator that converts JavaScript and other code like JSX to a more compatible version of Javascript
Webpack: creates an easily transferable bundle of your code, dependencies, and packages into a single bundle. This makes your code compatible with any browser.

Redux: offers a different way to how we manage state which changes our code flow
-all our data is kept in the state
-the state is just a plain JavaScript object (like the rest of Redux)
-the difference lies in the fact that Redux state isn’t part of the component tree (because we store all our data in our application in a JavaScript object known as the store which is separate from our components) which allows isolate and manipulate any part of our data with any component by connecting them
-redux stores all application state (data) into a store
-components that need to be updated by the state changes can ‘subscribe’ to the store
-the store plays the role as the middleman for any state changes in the app
-all components get their state from the store and send state changes to the store, making data flow easier
-to change state we need an action that tells us the action type (which obtains information for how to update the state) in conjunction with our previous state to create an updated state

An example of my integration of Redux into my project started with the following in my App.js component.

Below is the before Redux integration:

componentDidMount() {fetch("http://localhost:3000/concerts").then(response => {return response.json();}).then((responseJSON) => {console.log(responseJSON);this.setState(() => {return {concerts: responseJSON}}, () => console.log(this.setState) )});});

In the react version we are making a fetch request to get all an array of concert objects. ComponentDidMount is a lifecycle method that is invoked immediately after a component is mounted. As long as we are in a component, the setState function comes from Component extension which is an example of built in functionality. We call setState() immediately after to trigger a rerender which happens before the browser updates the screen.

componentDidMount() {
this.props.newFetchConcertsWithDispatchFn()
}
...const mdp = (globalDispatch) => {return {newFetchConcertsWithDispatchFn: () =>
globalDispatch(newFetchConcerts())
}}const msp = (globalState) => (globalState)export default connect(msp,mdp)(App);

With Redux we are using props in componentDidMount and invoking the function newFetchConcertsWithDispatchFn. In redux, all our information is passed to props which is accessed through this.props. We add {connect} from react-redux into our import and export in App.js so the return values of msp (mapStateToProps) and mdp (mapDispatchToProps) will be passed into the properties of this specific component. We do this by adding msp and mdp as arguments in the exports where msp allows you access to global state and mdp allows you to manipulate the store. MapStateToProps should refer to the local state (this.state) which is now located in the reducer. To add data to the global store we have to update by reconfiguring the lifecycle method componentDidMount. The function newFetchConcertsWithDispatchFn is an action from our actions file that. The function takes in an argument of the dispatch function which allows us to manipulate our global state from the action creator. Dispatch is meant for sending content to the reducer. We use mapDispatchToProps for when we don’t have a direct connection to redux.

Here is the ConcertActions file which contains event descriptors and their associated fetch and post requests:

export const addConcert = (concert) => ({ type: "ADD_CONCERTS", payload: concert})export const fetchConcerts = () => {return (dispatch) => {dispatch({ type: 'LOADING_CONCERTS'})fetch("http://localhost:3000/concerts").then(response => {return response.json()}).then(responseJSON => {// console.log(responseJSON)dispatch({ type: 'ADD_CONCERTS', concerts: responseJSON })})}}export const createConcert = (concert) => {return (dispatch) => {const configObj = {method: 'POST',headers: {"Content-Type": "application/json","Accepts": "application/json"},body: JSON.stringify(concert)}fetch("http://localhost:3000/concerts", configObj).then(res => res.json()).then(json => {dispatch(addConcert(json))})}}export const newFetchConcerts = () => {return (dispatch) => {dispatch({ type: 'LOADING_CONCERTS'})fetch("http://localhost:3000/concerts").then(response => {return response.json()}).then(responseJSON => {// console.log(responseJSON)dispatch({ type: 'ADD_CONCERTS', concerts: responseJSON })})}}

Below is the ConcertReducer which takes the current state and the action to handle dispatched actions and update state:

const concertsReducer = (state = { concerts: [], loading: false }, action) => {switch(action.type) {case 'LOADING_CONCERTS':return {...state,concerts: [...state.concerts],loading: true}case 'ADD_CONCERTS':return {...state,concerts: action.concerts,loading: false}case 'DELETE_CONCERT':return {concerts: state.concerts.filter(concert => concert.id !== action.payload.id),...state}default:return state;}}export default concertsReducer;

As you can see, redux allows us to manage state in a more effective and clean way. The store unburdens our components to be able to better follow the concept of single responsibility principle. Without the components keeping state, they rely on the store to be the single source of truth. By this meaning, we understand that the only way data can be changed is through a dispatch action which will change state within the reducer. Components will observe and if they are ‘subscribed’ to the reducer will change accordingly.

To see my full project check out my github at here

Thanks for reading!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Melissa Guachun

Melissa Guachun

Software Developer and visual artist based in NYC. Join me on my journey to coding enlightenment or a torrential mental breakdown, whichever comes first.