Creating a News Feed App With React and Redux — Part 2

Turbo 360
Turbo 360
Aug 26, 2017 · 11 min read

Now, we just set up our sidebar so that when we add a feed we see a visual change and see the actual feed, but if you refresh your browser you will notice they disappear.

Our component needs to fetch all the feeds when it first mounts, not just keep track of the new feeds we add.

Luckily, there is a react component lifecycle method called ComponentDidMount, which allows us to give our component instructions when it mounts (Lines 17–28). The logic is very similar to what we just did in our updateFeed function, except we using the turbo fetch method to fetch all our feed objects that are currently stored on our back end.

Now if you reload your page, you should see all the feed objects you created in your sidebar, much better!

Alright, now it’s time to implement Redux. I am not going to explain too fully as we set up all the pieces, so just follow along, and once we are all set up and functioning it will make more sense and we can dive in more deeply.

First, we are going to set up a reducer and an action to move our asynchronous actions into redux instead of in our individual component.

$ cd src/reducers$ touch feedReducer.js

We can adjust our index.js now to include our new reducer:

We also want to add a constant to our src/constants/index.js file which is a centralized location where we keep a reference to all actions that we will be dispatching in our application.

Then, let’s create our reducer as follows:

If you remember earlier in our project root, I mentioned that our application was wrapped in the Provider component, which gives our application component’s access to the application store. This store is configured in the src/stores/index.js file below. The store is made up of numerous reducers, so we need to include our reducer in our store as well.

This is already configured we just need to change line 3 to include our new reducer and add line 12 so that our reducer is included in our global store:

Note in line 12 we give the feed key to the feedReducer; we can use whatever we want here but whatever you use will come in use shortly when we are back in our component.

Finally, let’s create an action, so we can get all this working with some real network requests:

And finally, let’s make the changes in our Sidebar component so we reference all our redux actions and states, instead of our local actions and states.

Now that we have all the pieces complete, let’s look at how all this fits together, starting from our component (Sidebar.js).

You will notice in lines 3 and 4 above, we import connect from the ‘react-redux’ node module, as well as actions from our local project.

At the end of our component in our module export, we are now performing some additional commands as we connect our stateToProps and dispatchToProps functions, which map both our redux store to props as well as our redux actions to props that are usable in our component.

These functions are defined just above in lines 84–94, and we will start with dispatchToProps to see how this all fits together. The dispatchToProps function maps our fetchFeeds action to a prop we can call locally, which in line92 we cleverly names “fetchFeeds” as well.

We can now call the redux action in our component, which we do on line 19 (this.props.fetchFeeds). If we did not map these as just described, this would not be possible.

Once our component mounts and the action is called, the constants.FILES_RECEIVED action is dispatched (this is defined in the actions file).

You can think of the switch statements in our reducers as very similar to event listeners, so in our fileReducer, our FILES_RECEIVED case is triggered which tells our reducer what to do with the new data received. The reducer performs some operations which we defined, and returns a new state which updates our store.

Now, in order for the component to get the new data, it cannot be referencing its local state, it needs to reference the store so it can keep up to date with any changes to our feed data.

Now, back to our stateToProps function at the bottom of the Sidebar.js component. If you remember when we configured our store we pointed the “feed” key to reference the feedReducer. That is why we map “feed” to “state.feed” in our stateToProps function. This maps our global store.feed to be accessed via props in our component, via “this.props.feed”.

We then change all the references to our local array to reference out store array of feeds (line 70 — this.props.feed.all).

Now that we are tracking the redux data instead of the old local data, our component automatically updates any time any relevant store data updates.

This is the beauty of react-redux. In our component render function, we just tell our components exactly what to render and not concern itself with data changes(i.e. you always render “all of the feeds”). We let our redux set up above deal with how that data is fetched/updated, etc. and our render function always reflects the appropriate changes (i.e. a user deleted a feed or added a feed, so “all of the feeds” is now slightly different).

I know this seems a bit confusing and not necessarily like it’s worth all the trouble, but through some repetition it will all come together and all the pieces will make sense, and you’ll start to wonder how you ever worked with react data any other way.

Now, we are going to repeat the same steps with similar logic to move the local action and state for the addFeed flow into redux.

We need to add a constant in our constant file:

Create the actual action in our action file:

In our reducer, we need to add the listener for when the constants.FEED_CREATED action is dispatched to that we can update our store:

And finally, let’s call the redux action in our component instead of our current function (note where we map the actual function to our component props on line 86, and call the action with this.props.createFeed() on line 34:

Give it a try, and everything should be working (you should see your newly created feed automatically render as it is loaded into the store, as your sidebar is rendering all the feed objects in your store.

One quick adjustment, you will notice when we create a feed our inputs do not clear out.

This is easy to fix, and called a controlled input. Just add a value attribute to the inputs that is set equal to your local state, and clear the state when you successfully add a new feed:

Finally, it might be a good idea to go through and get rid of a lot of the console.log statements we have lying around and no longer need.

Lastly, we have a lot of test data, so we should also go into our turbo360.co/dashboard and delete some of the dummy data:

Click the edit button and then delete the individual entries we no longer want:

Hopefully this section gave a better idea of the basics of the overall redux flow in an application and gives a good reference point for setting up future components.

Next up, we will make several additional components and now that we have a solid foundation to build upon and basic understanding of redux, finish building out a fully functioning news reader.


So far, we have mostly been working in our presentation component, Sidebar.js. A react code base can unfortunately sometimes become pretty unwieldy and difficult to follow if some sort of basic pattern isn’t followed in regards to structure.

One popular approach I often use when structuring an application is separating my components into 3 separate types; presentation (sometimes called view) components, container components, and layout components.

The distinction between each will become pretty clear as we build out our application, but usually the bulk of our actions and component logic take plus in our container components.

That being side, we have some refactoring to do! First up, let’s create a Feeds.js file for our new component and import it into the appropriate index.js file.

$ cd src/components/containers
$ touch Feeds.js

Then, lets’ create an extremely basic Feeds Component and import it into our Sidebar.js and make sure it shows up, just to confirm everything is working and configured properly thus far.

And notice the changes in Sidebar, lines 3 and 65 below:

Again, we are just making sure everything is set up properly.

As long as you see the new text from your Feeds Container, it’s time to begin refactoring.

Basically, we want to move the ability and the responsibility of fetching and rendering the list of feeds, to the new Feed Container (everything you see here is being literally copied and pasted from Sidebar.js to the proper component):

Following the same approach, let’s actually make another container for the creation of the individual feeds, called AddFeed:

$ cd src/components/containers
$ touch AddFeed.js

And as usual, don’t forgot to add the new component to our index:

We then move all of the code relevant with taking the user input and creating the actual feed from Sidebar.js to our new AddFeed.js component as follows:

After all this, our Sidebar.js is drastically smaller, and is left with just a basic render function and some html elements used for styling, along with our Feed and AddFeed components in lines 13 and 19:

To be honest, at this point maybe it’s not worth the complexity of having the entire sidebar component. I am going to remove the Sidebar component from our Home component, and just move all of the contents of Sidebar into the Home component directly:

Make sure everything is rendering properly, and then we can move on to actually selecting individual newsfeeds to render when the user clicks a feed.

Before, we get back into redux, let’s just create a simple action that is called when the user click’s one of the feed links. Let’s also pass in the individual feed object as a variable, so when the user clicks the alert they get to see the details of the feed they clicked:

Notice the new selectFeed method defined on line 11–15, along with line 23 where the method is bound to all the individual feed hyperlinks.

If everything is working, you will get an alert like below (click multiple links to make sure your alert contains different feed objects):

This is great, but eventually we are going to have other components, namely an actual Feed component rendering all of the individual stories, that will need to know which Feed is selected/active.

Since our other components will have the ability to access to our store, let’s set this all up in redux like we did earlier with our addFeed and fetchFeeds actions. In order to do so, we are going to have to add a constant in our constants file, add an action in our action file, and add a case statement in our feedReducer.js file, and then we can finally call the new action from our component directly. You will get used to this whole flow soon and it will eventually begin to feel like second nature, do not fear.

Create a constant:

Create our action:

Now, in our reducer we add a ‘selected’ property set to null in our initial state, and a case to set our selected property when we dispatch an action with a type of constants.SELECT_FEED:

And finally, we are going to add the action in our component in our dispatchToProps function, as well as calling the actual function in our selectFeed action we have already defined locally in the component:

Notice in line 22, we create a color variable which changes based on if our link is the selected property or not, and then assign it as a style of our list item on line 25. When you click the link, you will notice the list item text changes to blue. Now we know that clicking the link dispatches our select feed action and sets the selected property in our store to the relevant feed, but how does the color automatically change?

One of the most important concepts of react, is our components know when to re render based on of there will be any type of visual change. When the components props change (i.e. a different feed is selected), our component does not necessarily automatically re-render. However, because we declared that the item which is selected is blue and not red, react re-renders the component.

Also, please note that we don’t tell our component, if a feed item is clicked, then change the color to blue. We tell our component, the active feed should be blue, and as our render functions are deterministic, they handle the decision to re-render as described above. This may take some time to get used depending on what type of programming you have done in the past, but once you get used to it you will not go back.

Now we can select different feeds on our sidebar, but besides changing colors we are not doing much. Let’s work on rendering the actual RSS feeds once selected:

We will make a Feed.js container component, so as always add it to your index:

Now, if we go back to our home page, we are going to need to import our new Feed on line 2(currently non-existent) component. Then, we copy the contents of the section tag with the id of banner (because we will need to paste it in a second), and replace it with our new Feed component (line 11 below).

Now, for or actual feed component:

We take the basic html content we just copied to our clipboard, and paste it in our render function. We also import our standard connect function and connect our stateToProps and dispatchToProps functions to our store, as we are going to need to reference our feeds data which we would otherwise not have access to.

In lines 8–9, we use some basic javascript logic to get the actual name of the selected feed, or return a default string if nothing is selected. This is important, because in line 13, you will see the change we made from the original static html we pasted in, as we are going to render our h1 tag contents dynamically based on the selected feed. We cover for the null scenario as mentioned above, so we can now just render the name variable in our JSX expression (the content between the curly braces/brackets).

Now try clicking some different feeds on the left, and watch your content dynamically change! In the next section, we will work on rendering the entire RSS feeds when selected and finish off our app!

)

Turbo 360

Written by

Turbo 360

Launch Your Site on Turbo360 - www.turbo360.co

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade