6 min read

In this article by Sven A. Robbestad, author of ReactJS Blueprints, we will cover the following topics:

  • Understanding Webpack
  • Adding Redux to your ReactJS app
  • Understanding Redux reducers, actions, and the store

(For more resources related to this topic, see here.)

Introduction

Understanding the tools you use and the libraries you include in your web app is important to make an efficient web application. In this article, we’ll look at some of the difficult parts of modern web development with ReactJS, including Webpack and Redux.

Webpack is an important tool for modern web developers. It is a module bundler and works by bundling all modules and files within the context of your base folder. Any file within this context is considered a module and attemptes will be made to bundled it. The only exceptions are files placed in designated vendor folders by default, that are node_modules and web_modules files. Files in these folders are explicitly required in your code to be bundled.

Redux is an implementation of the Flux pattern. Flux describes how data should flow through your app. Since the birth of the pattern, there’s been an explosion in the number of libraries that attempt to execute on the idea. It’s safe to say that while many have enjoyed moderate success, none has been as successful as Redux.

Configuring Webpack

You can configure Webpack to do almost anything you want, including replacing the current code loaded in your browser with the updated code, while preserving the state of the app.

Webpack is configured by writing a special configuration file, usually called webpack.config.js. In this file, you specify the entry and output parameters, plugins, module loaders, and various other configuration parameters.

A very basic config file looks like this:

var webpack = require('webpack');
module.exports = {
  entry: [
    './entry'
  ],
  output: {
    path: './',
    filename: 'bundle.js'
  }
};

It’s executed by issuing this command from the command line:

webpack --config webpack.config.js

You can even drop the config parameter, as Webpack will automatically look for the presence of webpack.config.js if not specified.

In order to convert the source files before bundling, you use module loaders. Adding this section to the Webpack config file will ensure that the babel-loader module converts JavaScript 2015 code to ECMAScript 5:

module: {
  loaders: [{
    test: /.js?$/',
    loader: 'babel-loader',
    exclude: /node_modules/,
    query: {
      presets: ['es2015','react']
    }
  }]
}

The first option (required), test, is a regex match that tells Webpack which files these loader operates on. The regex tells Webpack to look for files with a period followed by the letters js and then any optional letters (?) before the end ($). This makes sure that the loader reads both plain JavaScript files and JSX files.

The second option (required), loader, is the name of the package that we’ll use to convert the code.

The third option (optional), exclude, is another regex variable used to explicitly ignore a set of folders or files.

The final option (optional), query, contains special configuration options for Babel. The recommended way to do it is actually by setting them in a special file called .babelrc. This file will be picked up automatically by Babel when transpiling files.

Adding Redux to your ReactJS app

When ReactJS was first introduced to the public in late 2013/early 2014, you would often hear it mentioned together with functional programming. However, there’s no inherent requirement to write functional code when writing the ReactJS code, and JavaScript itself being a multi-paradigm language is neither strictly functional nor strictly imperative. Redux chose the functional approach, and it’s quickly gaining traction as the superior Flux implementation.

There are a number of benefits of choosing a functional, which are as follows:

  • No side effects allowed, that is, the operation is stateless
  • Always returns the same output for a given input
  • Ideal for creating recursive operations
  • Ideal for parallel execution
  • Easy to establish the single source of truth
  • Easy to debug
  • Easy to persist the store state for a faster development cycle
  • Easy to create functionality such as undo and redo
  • Easy to inject the store state for server rendering

The concept of stateless operations is possibly the number one benefit, as it makes it very easy to reason about the state of your application. This is, however, not the idiomatic Reflux approach, because it’s actually designed to create many stores and has the children listen to changes separately.

Application state is the only most difficult part of any application, and every single implementation of Flux has attempted to solve this problem. Redux solves it by not actually doing Flux at all but is an amalgamation of the ideas of Flux and the functional programming language Elm.

There are three parts to Redux: actions, reducers, and the global store.

The store

In Redux, there is only one global store. It is an object that holds the state of your entire application. You create a store by passing your root reducing function (or reducer, for short) to a method called createStore.

Rather than creating more stores, you use a concept called reducer composition to split data handling logic. You will then need to use a function called combineReducers to create a single root reducer.

The createStore function is derived from Redux and is usually called once in the root of your app (or your store file). It is then passed on to your app and then propagated to the app’s children.

The only way to change the state of the store is to dispatch an action on it. This is not the same as a Flux dispatcher because Redux doesn’t have one. You can also subscribe to changes from the store in order to update your components when the store changes state.

Actions

An action is an object that represents an intention to change the state. It must have a type field that indicates what kind of action is being performed. They can be defined as constants and imported from other modules.

Apart from this requirement, the structure of the object is entirely up to you. A basic action object can look like this:

{
  type: 'UPDATE',
  payload: {
    value: "some value"
  }
}

The payload property is optional and can be an object, as we saw earlier, or any other valid JavaScript type, such as a function or a primitive.

Reducers

A reducer is a function that accepts an accumulation and a value and returns a new accumulation. In other words, it returns the next state based on the previous state and an action.

It must be a pure function, free of side effects, and it does not mutate the existing state.

For smaller apps, it’s okay to start with a single reducer, and as your app grows, you split off smaller reducers that manage specific parts of your state tree.

This is what’s called reducer composition and is the fundamental pattern of building apps with Redux.

You start with a single reducer, and as your app grows, split it off into smaller reducers that manage specific parts of the state tree. Because reducers are just functions, you can control the order in which they are called, pass additional data, or even make reusable reducers for common tasks such as pagination.

It’s okay to have multiple reducers. In fact, it’s encouraged.

Summary

In this article, you learned about Webpack and how to configure it. You also learned about adding Redux to your ReactJS app.

Apart from this, you learned about Redux’s reducers, actions, and the store.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here