React and Redux Tutorial Trending GitHub – Part 2

Trending Repos - Featured Image

This is the second post in a series titled “React and Redux Tutorial Trending GitHub”. It is my attempt to teach what I’ve learnt about Redux to make sure I’ve actually learned it.

The series is aimed at beginners. The final app doesn’t need Redux but I used it as a stepping stone to more complex apps. I rate Todo Apps, but I wanted to create something I couldn’t just cut and paste away my problems if I got stuck. I encourage you not to do the same.

Over the course of the series I’m gradually building an app that looks like the image at the top of this post. The series is made up of the following posts:

  1. Introduction, setup and add a Header component
  2. Add static data to Redux (this post)
  3. Display the static data
  4. Load data from an API during application start
  5. Add a Search Button

So far, we’ve just displayed a H1 on the screen. In this post we’re going to add some hard coded static data into Redux. We’ll create a simple reducer and connect our app to Redux.

Sample Static Data

Before getting into some code, let’s grab some sample data to display.

There are a few reason I like to use static data during the initial development of my apps. First, I have control of the data. If I want to try different values, I can edit it easily. Second, it’s quick to get the data so there’s no waiting for the network. Finally, you don’t even need a network connection, so you can develop anywhere.

There is a possible negative with this approach though. As there is no network latency, you won’t notice any impact it has on user experience. Thankfully it’s easy to add it back in as we’ll see later.

For now, fire up a browser or tool of your choice to query a remote API. I like to use Postman but the choice is yours. We want to show today’s trending repositories, so we will use this endpoint

In Postman I ended up with a query configured like this:

Trending GitHub - Part2 - Postman Query

Trending GitHub – Part2 – Postman Query

Which ends up with a query string looking like


Breaking the parameters down explains it a little:

  • q – This is the actual query. I’m looking for repos created since July 10th
  • sort – the field to sort by, in this case the number of stars
  • order – we want the results in descending order, I.e. largest first
  • per_page – the number of results to return

When you run the query, you should receive a lot of JSON back. We’ll use this in a moment as the initial state for one of our reducers. Before that, we need to wire up Redux into our app.

Wiring Up Redux

The starter kit makes this simple. Change the index.js file to (changes highlighted):

/* eslint-disable import/default */

import React from 'react';
import { render } from 'react-dom';
import TrendingRepos from './components/TrendingRepos';
import '../node_modules/bootstrap/dist/css/bootstrap.css';
import { Provider } from 'react-redux';
import configureStore from './store/configureStore';

const store = configureStore();

  <Provider store={store}>
    <TrendingRepos />

If you want to just cut and paste code, jump to the . Otherwise, I’ll try to explain what is happening here.

First, two import statements were added. Provider from react-redux makes the state in Redux available to all other child components. That is components wrapped by a Provider component. We’ll see how to do that later but you can read the docs if you want more information now

The second import adds a configStore function that is part of the starter kit. It wraps Redux’s createStore, setting up our environment with the redux devtools and hot-reloading. It also combines any reduces we have configured in src/reducers/index.js. That’s what we’ll do now.

Designing application state

The starter kit is setup so an initial state of the application can be stored in a file and loaded into Redux. I like this approach as it makes you think about the design of your application state before coding. Doing that now, we know that we want to store some repos. Create a file called initialState.js in src/reducers containing:

export default {
  repos: [

A field in the top level of our state called means we need to pass a reducer called repos to combineReducers. As you will see, the reducer itself doesn’t need to be called repos, just the key passed to combineReducers. Let’s create that now.

Create a Repos reducer

In `src/reducers’ create a file called reposReducer.js and put the following code:

import initialState from './initialState';

export default function reposReducer(state = initialState.repos, action) {
  switch(action.type) {
      return state;

Line 1 imports the initial state we created in the last step. We’re then taking advantage of default parameters to set the state parameter to the repos array if it isn’t already set. It won’t be set when the app initializes, hence it being called initial state. As we have no actions yet, the switch statement is not needed. I like to leave it in to make adding future actions easier.

The next step is updating our store to use this reducer, so let’s do that now.

Updating our store

Update src/reducers/index.js with the following changes:

import { combineReducers } from 'redux';
import repos from './reposReducer';

const rootReducer = combineReducers({
export default rootReducer;

As you can see, we import reposReducer and take advantage another ES6 feature called Object Literal Property Value Shorthand. That’s a mouthful to say { repos } is the same as {repos : repos}.

We’ve now finished setting up Redux with our application state. All that remains is connecting Redux to our app and displaying something.

Connecting to Redux

In this part of the tutorial, as we’ve just done a lot of wiring up, I just want to display the number of repos we have. Next time we’ll concentrate on making the result look pretty.

We’ll lay the foundation for Presentational and Container Components by creating a new file in src/containers called ReposListContainer with this code:

import React, {Component} from 'react';
import { connect } from 'react-redux';

const ReposList = ({repos}) => {
    return (
        <h1> {repos.length} </h1>
const mapStateToProps = (state) => {
  return {
    repos: state.repos
const ReposListContainer = connect(mapStateToProps)(ReposList);

export default ReposListContainer;

This is standard Redux and the official documentation does a
very good job of explaining it.

The key thing to realise is that our ReposList component will now have a props variable called repos that contains the value of state.repos. If you remember state.repos is our array of repos.

We’ll refactor ReposList to be a component in the next part. For now, this should display the number of repos we have, 10. All that’s left is to add ReposListContainer to our app.

Render the list

Change src\components\TrendingRepos.js to

import React, {Component} from 'react';
import ReposListContainer from '../containers/ReposListContainer';

class TrendingRepos extends Component {
    render() {
        return (
            <div className="container">
                <h1>Today's Trending Github Repos</h1>
	     <ReposListContainer />

export default TrendingRepos;

We’ve imported the new container component and used it. If npm run start –s is still running (if it’s not, run it again) you should be able to switch to your browser and see the below:

Trending GitHub - Part2 - Number Only

Trending GitHub – Part2 – Number Only

Nothing exciting yet, but it shows we’ve hooked things up properly. Another quicker way to verify we’ve done our job properly is to install the React Developer Tools. If you have that installed, select the TrendingRepos component and check it’s props. If you repos in there like the image below, you’ve done it right.

Trending GitHub - Part2 - React Developer Tools

Trending GitHub – Part2 – React Developer Tools

End of Part 2

If you’ve made it this far, thank you for sticking with it. Our app is beginner to take shape. It’s not pretty, but the data we’ll eventually receive from GitHub is in Redux. Next time, we’ll displaying the data in a nice table.

If you have any comments, questions or problems, please let me know below or contact me on twitter.

No comments yet, your thoughts are welcome.

Leave a Reply

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