React-Redux: Line-by-Line

Shorthand reasoning through the start of a basic React app

Sara Harvey
4 min readFeb 11, 2021
Photo by cottonbro from Pexels

I created a simple app, “Two-Minute Media,” for my Flatiron School project around the idea that no emotion lasts for more than two minutes. So, if you’re momentarily upset or anxious or angry, open the app and choose a short story to read or hear, or have one chosen at random by the program.

I started by creating the app, adding Redux and Thunk, the router, provider and store. As Two-Minute Media started taking shape, I wanted to make sure I understood what each chunk of code accomplished.

So, this isn’t so much as a “how to,” as it is a, “How is it doing that?” in four annotated files.

//src/index.jsimport React from 'react';
// The react-dom package provides DOM-specific methods that can be used at the top level of an app (React documentation)import ReactDOM from 'react-dom';
// "When used with React, a <Provider> exists to wrap the application, and anything within the Provider can have access to Redux" (tutorial, Tania Rascia)import { Provider } from 'react-redux';
import store from './store.js';
import App from './App';
import './index.css';
// Anything within the provider can have access to ReduxReactDOM.render(
<Provider store={ store }>
<App />
</Provider>, document.getElementById("root")

From there, I initialized the store.

// src/js/store/index.js// Store -- JS object that holds a Redux app's state. 
// Props -- data passed from parent
// State -- mutated data (updated props via a click, for example)
// compose lets you enhance a store with applyMiddleware and dev tools (React documentation)import { createStore, applyMiddleware, compose } from "redux";
import rootReducer from "./reducers/index";
// Thunk handles asynchronous calls when working with Redux:
// a. dispatches an action, tells user we're loading the data,
// b. makes a request to the API,
// c. waits for the response and then dispatches another action
with the response data
import thunk from "redux-thunk";
// More information on
storeEnhancers
const storeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
// Initialize the store with a reducer function (here, rootReducer), passed to createStore. Store handles all dispatched actions and calculates an entirely new state every time (Redux documentation, Learn.co)const store = createStore(
rootReducer,

// storeEnhancers is used with
Redux devtools
storeEnhancers(applyMiddleware(thunk))
);
export default store;

Then, I created the reducer.

//src/reducers/index.js// Reducer -- a JS function with two parameters: current state and action. When an action is dispatched, the store forwards a message 
(the action object) to the reducer
const initialState = {
stories: []
};
// Initial state is passed in as default parameter. So, this code returns initial state.function rootReducer(state = initialState, action) {
// Checks the action type, "when action is this, do this."
if (action.type === "DATA_LOADED") {
// Returns a new JS object to keep the original state unaltered.
return Object.assign({}, state, {
// This preserves the original array.
stories: state.stories.concat(action.payload)
});
}
// Resulting state is just a copy of the initial state (tutorial, Valentino Gagliardi) return state;
}
export default rootReducer;
// actions signal reducers to produce the app's state

Then, I worked on creating the action.

// src/actions/index.js// Actions are JavaScript objects
// Thunk is an NPM package, middleware (
Learn.co)
export function getData() {return (dispatch) => {
dispatch({ type: 'START_ADDING_DATA'});

// fetch() returns a Promise -- "data will be available when we can access it"
fetch('https://two-min-media-api.herokuapp.com/stories')


// then() accesses data when promise resolves, parses it into JSON

.then(resp => resp.json())
// "when we receive the data ..."
// Thunk -- fetch() returns a function (vs. an object). That function receives the store's dispatch function as its argument. With that, we can dispatch multiple actions from inside that returned function. .then(json => dispatch({ type: 'DATA_LOADED', payload: json.data }))
};
}
// Action must be an object with a type property
// Type property, required, drives how the state should change
// Payload property, not required, describes what should change

React-Redux challenges

For some reason it was hard for me to grasp that individual stories from the API are templated in the “little” file, Story.js. Then, Stories.js handles them as a group, and StoryContainer.js returns a selection of the group to the browser. It helped me to think of the files as nesting dolls, separated concerns making one lovely piece of folk art (er, code).

Thanks for reading, and let me know if I can do anything to improve this post. Visit the front end repo here, https://github.com/Sara-Harvey/two-min-media-frontend, and back end here, https://github.com/Sara-Harvey/two-min-media-api.

--

--

Sara Harvey
0 Followers

Ruby, JavaScript, coding, writing