Our Blog

Let us find tech solutions together

Dec 03

A Usable Bootstrap With React Slingshot

By Andrew Lombardi | Comments

 

Getting started with React can be a bit daunting, and as with using things like AngularJS I’ve found that using a bootstrap is a great way to start. With that in mind, I’ve chosen the wonderful react-slingshot from @housecor. It contains a demo which can be removed with an npm script and from which we’ll extract what I feel is most useful including: integration with redux, react-router, and redux-thunk.

Most React repositories seem to dispense with build tools and instead use a mixture of npm scripts and webpack to achieve what it needs to achieve. Just recently a new package manager came out to unseat the stalwart in npm, we’re using yarn, please follow the install instructions for your particular environment. Clone the react-slingshot repository using the following git command:

1
% git clone git@github.com:coryhouse/react-slingshot.git

First thing we’ll do after cloning react-slingshot locally is remove the demo as it isn’t useful any longer

1
yarn remove-demo

Main entrypoint

Let’s add the necessary items for using redux and integrating react-router. Open up the src/index.js and paste the following in:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* eslint-disable import/default */
import React from 'react';
import {render} from 'react-dom';
import { Provider } from 'react-redux';
import { Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';

import routes from './routes';
import configureStore from './store/configureStore';

const store = configureStore();
const history = syncHistoryWithStore(browserHistory, store);

render(
  <Provider store={store}>
    <Router history={history} routes={routes} />
  </Provider>,
  document.getElementById('app')
);

Let’s take this in chunks, the eslint bit is because there’s no default export in this file and we want eslint to ignore that. Then we have imports for bringing in react, redux, and the integration with react-router and redux.

1
2
3
4
5
import React from 'react';
import {render} from 'react-dom';
import { Provider } from 'react-redux';
import { Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';

The bootstrap already contains a working version to configure the store, and has the integration with redux‐thunk for the middleware. We call the exported function to configure the store, and then syncHistoryWithStore(browserHistory, store) will save our router state in the redux store.

1
2
3
4
5
import routes from './routes';
import configureStore from './store/configureStore';

const store = configureStore();
const history = syncHistoryWithStore(browserHistory, store);

This snippet is the entrypoint for our application. The Provider component is offered by redux and allows us to wrap all other components with access to our store, and inside that we add the Router component with access to our store-saved history, and the routes which we will define in the next section. That’s it for our index module, let’s move on to defining some simple routing.

1
2
3
4
5
6
render(
  <Provider store={store}>
    <Router history={history} routes={routes} />
  </Provider>,
  document.getElementById('app')
);

Routes

Now we’ll define our routes module which was referenced in the index file. Create a new file in src/routes.js and paste the following in.

1
2
3
4
5
6
7
8
9
10
import React from 'react';
import { Route, IndexRoute } from 'react-router';

import HomePage from './pages/HomePage';

export default (
  <Route path="/">
    <IndexRoute component={HomePage}/>
  </Route>
);

This is a typical react-router file, and you can browse the documentation to find more ways to customize things.

Pages

You may have notice we’ve identified another missing file src/pages/HomePage.js, which we will create now.

1
2
3
4
5
6
7
8
9
import React from 'react';

const HomePage = () => {
  return (
    <h1>Hello, World!</h1>
  );
};

export default HomePage;

This is the simplest of components, a functional stateless component which merely outputs Hello, World! wrapped in an H1 tag. If you attempt to run things now you will still receive errors in the reducers directory. While out of the scope of this quick tutorial, reducers are how an application’s state changes in response to something happening, you can read more in the Redux docs.

Let’s open src/reducers/index.js and modify with the following:

1
2
3
4
5
6
7
8
import { combineReducers } from 'redux';
import {routerReducer} from 'react-router-redux';

const rootReducer = combineReducers({
  routing: routerReducer,
});

export default rootReducer;

Remember, we added react-router-redux to our index module, so as our first reducer we need to at the routerReducer to the list of reducers offered up in the combineReducers call. It’s in this file that you can define more reducers to be included in your redux stack.

Fin

With that, browse to http://localhost:3000 and see the familiar “Hello, World!”. There is so much more to be done, we can dip into the redux portion and start defining actions, action creators, reducers, and use redux-thunk for the inevitable need for asyncronous calls in our action creators. This is a first step, stay tuned and we’ll dig even deeper into the React / Redux stack.

And if you weren’t in Sofia, Bulgaria for CodeMonsters/Java2Days this year, my presentation on React and Redux is available on slideshare. Thanks to everyone who was in attendance,