React is a JavaScript framework that was originally authored by Facebook. It’s currently maintained by Facebook and the open-source community. React was designed to enable users to easily build front-end user experiences. It uses encapsulated pieces of code - known as components - to form complex user interfaces. Each component has the ability to manage its own state. This allows the React component to keep track of any associated data and variables as the developer sees fit.
Developers can write a robust front-end application using strictly React, or they can use it together with the Redux framework. The Redux framework is another JavaScript-based framework that manages components’ state in a centralized and predictable manner. In this article we’ll go into how to quickly get up and running with both frameworks in your next project.
To get started, the makers of the React framework have created a convenient command that allows users to get up and running in no time. Call it from the command line/terminal as follows:
{% code-block language="js" %}
$ npx create-react-app my_app
// “my_app” is a generic app title
{% code-block-end %}
The npx tool is used for executing packages, as opposed to installing them. It also does not globally install the packages it executes.
Running this command creates the following file structure within a project directory with the same name as that which was passed into the create-react-app (CRA) command.:
{% code-block language="js" %}
my-app/
README.md
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
{% code-block-end %}
Next up in getting set up, we install a further set of dependencies that aren’t given to us by the CRA command.
First, enter the following to change into your newly created project directory and install the additional dependencies.
{% code-block language="js" %}
$ cd my_app
$ npm install redux react-redux axios react-router-dom redux-persistor redux-thunk
{% code-block-end %}
Each of these dependencies adds a necessary set of functionality that allows us to effectively leverage Redux in our React project. The installation of the “Redux” package is a given in this instance. The react-redux dependency is an official React binding for Redux that allows our React components to read data from the Redux store and dispatch actions to that store in order to update the data stored there.
Axios is a promise-based HTTP client that works with the browser and node. It is similar to the built-in fetch API, however, it is light-weight and its syntax is more straight-forward.
The other three dependencies (react-router-dom, redux persistor & redux-thunk) are optional. If you’re building a single page web application that doesn’t involve routing to other pages, then you can go right ahead and leave them out. Otherwise, they each provide much needed additional functionality;
Once you’ve installed your dependencies, you can go about setting up four files which, once complete, allow you to go about writing the logic specific to your project. The first file to be edited is the App.js file given to us by the CRA command. Modify this file as follows:
{% code-block language="js" %}
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import './App.css';
const App = () => {
return (
<div className = "App">
<switch>
<Route
exact
path= "< enter path here >"
component={ enter imported component here }
/>
</switch>
</div>
);
};
export default App;
{% code-block-end %}
The above set-up allows you to quickly input routes to relevant components and their associated paths. This app component is exported to be used in the “Root” component as seen below.
{% code-block language="js" %}
import React from 'react';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { persistStore } from 'redux-persist';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
const Root = ({ store }) => {
const persistor = persistStore(store);
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<Router basename={process.env.PUBLIC_URL}>
<App />
</Router>
</PersistGate>
</Provider>
);
};
export default Root;
{% code-block-end %}
The Root component receives the Redux store as a prop and that store is passed into the Provider as seen above. The store is also used to initialize the persistor which is in turn passed to the persistGate. The app component that we edited earlier is imported here and wrapped at the deepest level. The root component is exported. Next, we’ll see how to use it to render your app to the DOM.
The Root component is imported into the index.js file that was created by the CRA command. That file is then edited as follows:
{% code-block language="js" %}
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import persistedReducer from './reducers/index';
import Root from './components/Root';
import './index.css';
const store = createStore(persistedReducer, applyMiddleware(thunk));
ReactDOM.render(<Root store={store} />, document.getElementById('root'));
{% code-block-end %}
The root component that was imported is injected into the DOM by passing it to the render function with a store prop. The Redux store can be created in this file or abstracted to a file of its own and imported. I’ve chosen to demonstrate the former for simplicity.
To create the store, you pass in the reducer and any middleware that is being utilized. In this case the reducer combines redux-persist logic and is defined as follows in its own file:
{% code-block language="js" %}
import { combineReducers } from 'redux';
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';
*import your reducers here
const rootReducer = combineReducers({
// users: userReducer,
// posts: postReducer
// these are fictitious reducers included to demonstrate the syntax
});
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
export default persistedReducer;
{% code-block-end %}
In the above example, the combineReducers function from the Redux library is used to create a rootReducer. This is, in turn, used with a persistConfig object (defined exactly as seen here) to create the persistedReducer mentioned.
We now have our project fully configured to include our unique logic. We can define new components and import them into the App.js file for easy routing. We can also define our actions and reducers without having to worry about how to combine them and wire them up to carry out their functions.
There you have it - you now have a perfect platform on which to build something great, that users can enjoy, and that you can feel proud of.
Happy coding!
Photo by Filiberto Santillán on Unsplash
Career advice, the latest coding trends and languages, and insights on how to land a remote job in tech, straight to your inbox.