Learning Redux - Daniel Bugl - E-Book

Learning Redux E-Book

Daniel Bugl

0,0
45,59 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Build consistent web apps with Redux by easily centralizing the state of your application.

About This Book

  • Write applications that behave consistently, run in different environments (client, server and native), and are easy to test
  • Take your web apps to the next level by combining the power of Redux with other frameworks such as React and Angular
  • Uncover the best practices and hidden features of Redux to build applications that are powerful, consistent, and maintainable

Who This Book Is For

This book targets developers who are already fluent in JavaScript but want to extend their web development skills to develop and maintain bigger applications.

What You Will Learn

  • Understand why and how Redux works
  • Implement the basic elements of Redux
  • Use Redux in combination with React/Angular to develop a web application
  • Debug a Redux application
  • Interface with external APIs with Redux
  • Implement user authentication with Redux
  • Write tests for all elements of a Redux application
  • Implement simple and more advanced routing with Redux
  • Learn about server-side rendering with Redux and React
  • Create higher-order reducers for Redux
  • Extend the Redux store via middleware

In Detail

The book starts with a short introduction to the principles and the ecosystem of Redux, then moves on to show how to implement the basic elements of Redux and put them together. Afterward, you are going to learn how to integrate Redux with other frameworks, such as React and Angular.

Along the way, you are going to develop a blog application. To practice developing growing applications with Redux, we are going to start from nothing and keep adding features to our application throughout the book. You are going to learn how to integrate and use Redux DevTools to debug applications, and access external APIs with Redux. You are also going to get acquainted with writing tests for all elements of a Redux application. Furthermore, we are going to cover important concepts in web development, such as routing, user authentication, and communication with a backend server

After explaining how to use Redux and how powerful its ecosystem can be, the book teaches you how to make your own abstractions on top of Redux, such as higher-order reducers and middleware.

By the end of the book, you are going to be able to develop and maintain Redux applications with ease. In addition to learning about Redux, you are going be familiar with its ecosystem, and learn a lot about JavaScript itself, including best practices and patterns.

Style and approach

This practical guide will teach you how to develop a complex, data-intensive application leveraging the capabilities of the Redux framework.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 333

Veröffentlichungsjahr: 2017

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Learning Redux

 

 

 

 

 

 

 

 

 

 

Write maintainable, consistent, and easy to-test web applications

 

 

 

 

 

 

 

 

 

 

 

 

Daniel Bugl

 

 

 

 

BIRMINGHAM - MUMBAI

Learning Redux

 

Copyright © 2017 Packt Publishing

 

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

 

First published: August 2017

Production reference: 1260817

 

 

Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.

ISBN 978-1-78646-239-8

www.packtpub.com

Credits

Author

Daniel Bugl

Copy Editor

Dhanya Baburaj

Reviewer

Sergii Shvager

Project Coordinator

Devanshi Doshi

Commissioning EditorWilson D'souza

Proofreader

Safis Editing

Acquisition Editor

Shweta Pant

Indexer

Mariammal Chettiyar

ContentDevelopmentEditor

Roshan Kumar

Graphics

Jason Monteiro

Technical Editors

Akansha BathijaBharat Patil

Production Coordinator

Shraddha Falebhai

About the Author

Daniel Bugl is a developer, product designer and entrepreneur, focusing on web technologies. He currently lives in Vienna, Austria. He got into programming via game development as early as the age of 6. Later, at the age of 10, he first learned about web technologies such as HTML, CSS, PHP, and JavaScript.

During high-school, he contributed to the Ubuntu project, specifically the Ubuntu Beginners Team, supporting beginners with Linux and helping them get started with the community. He mentored some people who are full Ubuntu members now. He was also part of the Ubuntu-Youth council and leading the Ubuntu Austria LoCo (Local Community). Furthermore, he developed open source software, voluntarily translated software, and supported people on askubuntu.

He also did an internship as a researcher at the Vienna University of Technology, which would later become the university he studies at. Later on, he did an internship at Jung von Matt, an advertisement agency, where he collected practical experience in web development by developing a management panel.

He is now studying Business Informatics and Information Systems at the Vienna University of Technology (TU Wien) and is in the process of writing his bachelor thesis. At the university, he sometimes works as a tutor, on the Program Construction (entry-level programming), Usability Engineering, and Interface and Interaction Design courses.

Now, he is a contributor to many open source projects (including Redux and his own library, redux-undo) and a member of the React community on the Redux team. He also founded and still runs his own hardware/software startup TouchLay (touchlay), which helps other companies present their products and services. At his company, he constantly works with web technologies, especially React and Redux.

Acknowledgments

First of all, I would like to thank all of the people involved in the production of this book. The team at Packt was very nice and pleasant to work with. I would also like to thank Dan Abramov for creating Redux, helping me create redux-undo, and letting me create a recipe page in the Redux documentation. Him and his projects have been a great inspiration to me.

 

Furthermore, I would like to thank Nik Graf, Max Stoiber, and Andrey Okonetchnikov for organising the React Vienna Meetup, which deepened my interest in React and Redux. Special thanks for letting me give a talk on higher-order reducers! I would also like to thank my co-founder, Georg Schelkshorn, for running an amazing company with me – I would not get to use web technologies as much without it.

 

Finally, I would like to thank my family and friends for supporting me during the creation of this book. At this point, I would especially like to thank and send love to my girlfriend, Destiny Rebuck, for supporting me and caring for me during the most stressful part of the process--the weeks before publishing.

About the Reviewer

Sergii Shvager is a frontend developer who is passionate about React/Redux. He was born in Ukraine and is currently living in Berlin. He has worked on the frontend part of projects in different areas, such as e-commerce, game development, and services. He started his frontend experience with jQuery, Backbone.js, and Ext.js, and then switched to React/Redux stack.

He has had his own company that develops mobile applications. Currently, he is working at eBay Classified Group. 

 

 

I would like to thank my wife, Anna, for her support.

www.PacktPub.com

For support files and downloads related to your book, please visit www.PacktPub.com. Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.

https://www.packtpub.com/mapt

Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.

Why subscribe?

Fully searchable across every book published by Packt

Copy and paste, print, and bookmark content

On demand and accessible via a web browser

Customer Feedback

Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial process. To help us improve, please leave us an honest review on this book's Amazon page at www.amazon.com/dp/1786462397.

 

If you'd like to join our team of regular reviewers, you can e-mail us at [email protected]. We award our regular reviewers with free eBooks and videos in exchange for their valuable feedback. Help us be relentless in improving our products!

Table of Contents

Preface

About the book

What this book covers

What you need for this book

Who this book is for

Conventions

Reader feedback

Customer support

Downloading the example code

Downloading the color images of this book

Errata

Piracy

Questions

Why Redux?

Defining the application state

Defining actions

Tying state and actions together

Redux' three fundamental principles

Single source of truth

The read-only state

State changes are processed with pure functions

Introduction to the Redux ecosystem

Summary

Implementing the Elements of Redux

The Redux cycle

An action is dispatched

The main reducer function gets executed

Redux saves the new state

Strictly unidirectional data flow

Running code examples

Setting up a new project

Setting up Node.js

Initializing the project

Setting up webpack

Setting up Babel

Setting up the entry files

Running webpack

Setting up Redux

The template code

Implementing actions and action creators

Separating action types

ES2015 - import/export

Introducing action creators

ES2015 - arrow functions

ES2015 - import/export

Code example

Implementing reducers

Defining/importing action types

Defining action creators

Writing the posts reducer

The main structure of a reducer

ES2015 - using destructuring and the rest operator to parse the action

Handling CREATE_POST – creating a new post

Handling EDIT_POST – editing posts

Testing out our reducer

Writing the filter reducer

Combining reducers

Testing out the full reducer

Code example

The store – combining actions and reducers

Creating the store

Subscribing to state changes

Dispatching actions

Rendering the user interface

Creating sample data

Handling the user input

Code example

Summary

Combining Redux with React

Why React?

The principles of React

Setting up React

Rendering simple text

Rendering with JSX

Setting up JSX

Using JSX

Example code

First steps with React

Creating a simple React element

Creating a static React component

Functional components

Using components

Example code

Class components – dynamic React components

Creating a static class component

Creating a dynamic class component

Setting the initial state

React life cycle methods

Updating the state

Example – dynamic React component with timer

Example code

Connecting React to Redux

Presentational versus container components

Writing presentational components

Post component

PostList component

Example code

Writing container components

Implementing our own container component

Example code

Using React-Redux bindings to create a container component

Setting up React-Redux

Using React-Redux to create a container component

Using selectors

Example code

Building an application with Redux and React

The goal

Project structure

Defining the application state

Users state

Posts state

Filter state

Defining action types and action creators

Defining action types

Defining action creators

User action creators

Post action creators

Filter action creators

Implementing reducers

Users reducer

Posts reducer

Filter reducer

Root reducer

Setting up the Redux store

Code example – Redux-only application

Implementing the user interface

Implementing presentational components

User component

Post component

Timestamp component

PostList component

Filter component

FilterList component

Implementing container components

ConnectedPostList component

ConnectedFilterList component

Implementing the App component

Using <Provider>

Rendering the App component

Code example – React/Redux application

Further tasks

Summary

Combining Redux with Angular

Redux with Angular 1

Setting up Angular 1

Code example

Creating a basic Angular 1 application

Defining the module and controller

Code example

Setting up ng-redux

Redefining the controller

Dispatching actions from the user interface

Code example

Redux with Angular 2+

Setting up Angular 2+

Setting up @angular-redux/store

Code example

Summary

Debugging a Redux Application

Integrating Redux DevTools

Installing Redux DevTools

Creating a DevTools component

Connecting DevTools to Redux

Using the DevTools.instrument() store enhancer

Rendering DevTools

Implementing the persistState() store enhancer

Using multiple store enhancers

Implementing a simple session key provider

Do not re-dispatch on refresh

Using the store enhancer

Excluding Redux DevTools in production

Injecting the NODE_ENV environment variable with webpack

Adding new build scripts for production and development

Separating the production store from the development store

Implementing the development store

Implementing the production store

Importing the correct store

Importing and using configureStore()

Only loading the DevTools component in development mode

Running in production/development mode – example code

Setting up hot reloading

Hot reloading React components

Hot reloading other code with webpack

Hot reloading Redux reducers

Testing out hot reloading – example code

Using Redux DevTools

DockMonitor

Setup

Properties

LogMonitor

Setup

Usage

Properties

Inspector

Setup

Usage

Properties

SliderMonitor

Setup

Usage

Properties

ChartMonitor

Setup

Properties

Other monitors

Summary

Interfacing with APIs

Setting up the backend

The backend API

GET /api

Example output

GET /api/posts

Example output

GET /api/posts/:id

Example output

POST /api/posts

Example request

Example output

POST /api/posts/:id

Example request

Example output

GET /api/users

Example output

GET /api/users/:username

Example output

POST /api/users

Example request

Example output

POST /api/users/:username

Example request

Example output

Handling asynchronous operations with Redux

Dispatching multiple actions from an action creator

Defining action types

Creating an asynchronous action creator

Handling asynchronous action creators via middleware

Setting up redux-thunk middleware

Pulling data from an API into the Redux store

Extracting boilerplate code

Pulling posts from the API

Pulling users from the API

Fetching a single user

Fetching users when fetching posts

Handling loading state

Implementing the reducer

Implementing the component

Using the component

Handling error state

Implementing the reducer

Implementing the component

Using the component

Example code

Sending notifications to an API via Redux

Using asynchronous action creators

Creating users via the API

Creating posts via the API

Example code

Summary

User Authentication

JSON Web Tokens (JWT)

JSON Web Token structure

Header

Payload

Signature

Token

Using JSON Web Tokens

Implementing token authentication

Backend API

POST /api/login

Example request

Example output

POST /api/users

Example request

Example output

POST /api/posts

Example request

Example output

Secured routes

Storing the token in the Redux store

Defining the action types and action creator

Creating the reducer

Dispatching login action in the component

Testing out the login

Checking whether the user is logged in

Separating the header

Hiding/showing components when the user is logged in

Showing the currently loggedin user

Sending the token with certain requests

Example code

redux-auth

Summary

Testing

Setting up Jest

Testing automatically on every file change

Checking code coverage

Example code

Using Jest

Using test and describe

Matchers

.toBe or .not.toBe

Truthiness

Numbers

Strings

Arrays

Exceptions

All matchers

Testing asynchronous code

Callbacks

Promises

.resolves/.rejects

Setup and teardown

Running every time before/after each test

Running once before/after all tests

Scoping

Mocking

.mock property

Return values

Implementations

Special matchers

Testing Redux

Synchronous action creators

Reducers

Testing initial state

Initializing state with beforeEach()

Testing the setFilter action

Testing the clearFilter action

Reducers with async actions

Asynchronous action creators

Testing successful requests

Testing failing requests

Example code

Other tests

Testing React components

Summary

Routing

Creating a simple router

Defining the action types and action creator

Creating the reducer

Creating the page components

Creating the MainPage component

Creating the AboutPage component

Creating the Router component

Connecting the Router component to Redux

Using the Router component

Creating the Navigation component

Connecting the Navigation component to Redux

Using the Navigation component

Code example

Using a routing library

Introducing react-router

Static routing

Dynamic routing

Nested routes

More routing

Using react-router

Installing react-router

Defining the <Router> and <Route>

Defining the <Link>

Trying out the router

Marking the currently selected link

Using react-router with Redux

Do I need to connect my router to Redux?

Why deeply integrate my router with Redux?

Example code

Using react-router-redux

Installing react-router-redux

Using the routerMiddleware

Using the routerReducer

Using the ConnectedRouter

Testing out the router

Navigating by dispatching actions

Example code

Summary

Rendering on the Server

Why render on the server?

Current process to load the page

Using server-side rendering

Preparing for server-side rendering

Using the isomorphic-fetch library

Implementing server-side rendering

Handling the request/routing

Emulating the Redux store and browser history

Initializing the Redux store

Using react-router to decide which page to render

Handling react-router redirects

Injecting rendered React components into the index.html template

Injecting the preloaded Redux store state

Rendering the template file

Using the preloaded Redux store state

Caching the index page

Performance improvements

Summary

Solving Generic Problems with Higher-Order Functions

Making functions pure

Simple side effects

No side effects

Other side effects

Side effects and Redux

Creating higher-order functions

Functions as arguments

Functions as results

Solving generic problems with Redux

Higher-order reducers

Higher-order action creators

Higher-order components

Implementing generic undo/redo Redux

Setting up the counter application

Looking at the counter reducer

Implementing undo/redo in the counter application

Defining the action types

Defining the action creators

Defining the new state

Rewriting the counter reducer

Handling the counter-related actions

Handling the undo/redo actions

Creating undo/redo buttons

Trying out undo/redo

Example code

Implementing a generic undo/redo higher-order reducer

Defining the undoable higher-order reducer

Defining the initial state

Problems with our previous solution

A new kind of history

Defining a generic initial state

Handling generic undo/redo actions

Defining the action types

Defining the action creators

Implementing the enhanced reducer

Handling the undo action

Handling the redo action

Handling other actions (updating the present state)

Removing undo/redo logic from the counter reducer

Wrapping the counter reducer with undoable

Problems with our simple undoable higher-order reducer

Example code

Implementing redux-undo

Installing redux-undo

Wrapping our reducer with undoable

Adjusting the state selector

Importing the undo/redo actions

Debug mode

Example code

Summary

Extending the Redux Store via Middleware

What is middleware?

Express middleware

Creating our own middleware pattern

Sketching out the API

Creating the Middleware class

Defining the run method

Defining the use method

Using our own middleware pattern

Example code

Using the Redux store middleware

Implementing logging

Manual logging

Wrapping the dispatch function

Monkeypatching the dispatch function

Hiding monkeypatching

Getting rid of monkeypatching

Applying middleware

Implementing Redux middleware

Creating a middleware folder

Logging middleware

Error reporting middleware

Applying our middleware to the Redux store

Example code

Thunk middleware

Final tips and tricks

Designing the application state

Using indices

Normalized state

Organizing data in the application state

Updating an application state

Updating nested objects

Common mistake 1 - New variables that point to the same objects

Common mistake 2 - Only making a shallow copy

Correct approach - Copying all levels of nested data

Updating arrays

Inserting items

Removing items

Updating items

Mutating copies

Using libraries

Summary

Preface

About the book

Redux is a predictable state container for JavaScript apps. It helps you write applications that run in different environments (client, server, and native) and are predictable and easy to test. Additionally, Redux provides a great developer experience, such as live code editing and time traveling debugging. Redux can be used together with a view library, like React and Angular.

This book will start out teaching you why and how Redux works. We are going to learn about principles and restrictions that make your application more predictable. Afterwards, we will implement the basic elements of Redux to create a blog application. Next, we will connect Redux to a user interface by combining it with a view library, like React and Angular. Then we move on by implementing common functionality in our Redux application, such as user authentication, interfacing with APIs, writing tests, and routing. Finally, we are going to discuss extending Redux itself, by solving common problems with state management (such as undo/redo functionality) through higher-order reducers and middleware.

After reading this book, you will be able to write maintainable, predictable, consistent, and easy-to-test applications with Redux and React.

What this book covers

Chapter 1, Why Redux?, will teach you about the principles that make Redux special, and why Redux should be used in a project. It starts out with the motivation behind Redux (complexity of state management), then briefly covers how Redux works in practice and how certain restrictions allow us to write maintainable, predictable, consistent, and easy-to-test applications.

Chapter 2, Implementing the Elements of Redux, explains how to set up a project that is ready for Redux and the new JavaScript ES2015 syntax. Then, you are going to implement the basic elements of Redux and put a full Redux project together.

Chapter 3, Combining Redux with React, covers what React is and why it makes sense to use it. Then you will learn how to set up a project with React and connect Redux to it.

Chapter 4, Combining Redux with Angular, covers using Redux in combination with Angular 1 and 2+ (compatible with Angular 4).

Chapter 5, Debugging a Redux Application, covers how to integrate and use Redux DevTools in an application. Then it covers various Redux DevTools monitors, explaining how to configure and use them in practice. 

Chapter 6, Interfacing with APIs, teaches you how to handle asynchronous operations with Redux. Afterwards, this knowledge is used to pull blog posts and users from an API into the Redux store. Finally, you are going to learn how to dispatch actions that change the state in the frontend/client and the backend/server (creating users and posts).

Chapter 7, User Authentication, explains token authentication is and why using it over traditional cookie/session ID authentication makes sense. Next, you will learn how to use and implement an open standard of token authentication--JSON Web Token (JWT).

Chapter 8, Testing, covers using Jest, a testing engine, to write tests for all the elements of Redux. 

Chapter 9, Routing, covers how to implement routing with Redux and React, manually and by using libraries such as react-router and react-router-redux.

Chapter 10, Rendering on the Server, this chapter teaches you why server-rendering makes sense and what benefits we get from using this technique. Then, you are going to learn how to implement server-side rendering in a Redux/React application.

Chapter 11, Solving Generic Problems with Higher-Order Functions, explains about advanced patterns when developing JavaScript/Redux/React applications. It starts by teaching basic concepts such as pure functions, then moves on to higher-order functions. Next, you will learn how to use these concepts in a Redux/React application to implement generic undo/redo behavior.

Chapter 12, Extending the Redux Store via Middleware, teaches what middleware (specifically, Redux store middleware) is and how it can be used. To wrap up, this chapter ends with a section on general tips and tricks for developing Redux applications.

What you need for this book

Node.js v6.11.1 LTS

Needs to support nodejs (any Windows, macOS, Linux device)

Who this book is for

This book is for web developers who are already fluent in JavaScript, but want to extend their skills to be able to develop and maintain growing applications.

Conventions

In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning. Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "The next lines of code read the link and assign it to theBeautifulSoupfunction."

A block of code is set as follows:

{ "title": "Another test", "text": "Hello API!"}

When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

{ "username": "des", "realname": "Destiny"

,

"password": "test123"

}

Any command-line input or output is written as follows:

npm install --save react react-dom

Warnings or important notes appear like this.
Tips and tricks appear like this.

Reader feedback

Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.

Customer support

Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.

Downloading the example code

You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you. You can download the code files by following these steps:

Log in or register to our website using your e-mail address and password.

Hover the mouse pointer on the

SUPPORT

tab at the top.

Click on

Code Downloads & Errata

.

Enter the name of the book in the

Search

box.

Select the book for which you're looking to download the code files.

Choose from the drop-down menu where you purchased this book from.

Click on

Code Download

.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

WinRAR / 7-Zip for Windows

Zipeg / iZip / UnRarX for Mac

7-Zip / PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Learning-Redux. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Downloading the color images of this book

We also provide you with a PDF file that has color images of the screenshots/diagrams used in this book. The color images will help you better understand the changes in the output. You can download this file from https://www.packtpub.com/sites/default/files/downloads/LearningRedux_ColorImages.pdf.

Errata

Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title. To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.

Piracy

Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy. Please contact us at [email protected] with a link to the suspected pirated material. We appreciate your help in protecting our authors and our ability to bring you valuable content.

Questions

If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.

Why Redux?

If you have written a large-scale application before, you will know that managing application state can become a pain as the app grows. Application state includes server responses, cached data, and data that has not been persisted to the server yet.

Furthermore, the User Interface (UI) state constantly increases in complexity. For example, nowadays, routing is often implemented on the client so that we do not need to refresh the browser and reload the whole application in order to load a new page. Client-side routing is good for performance, but it means that the client has to deal with even more state (in comparison to using server-side routing).

As you can imagine, conflicts and inconsistencies in these various kinds of state can be hard to deal with. Managing all these states is hard and, if not managed correctly, application state can quickly grow out of control, like an untended garden.

If all of this was not bad enough, new requirements, such as optimistic updates and server-side rendering, become necessary to be able to keep up with the ever increasing performance demands.

State is difficult to deal with because we are mixing two concepts that can be very unpredictable when put together: Asynchronicity and Mutation.

Asynchronicity means that changes can happen anytime, in an asynchronous manner. For example, a user presses a button that causes a server request. We do not know when the server responds and, for performance reasons, we do not want to wait for the response. This is where Asynchronicity comes into play. We act on a response whenever it occurs, but it is unpredictable when this will happen.

Mutation means any change in the application state, such as storing the result from the server response in our application state or navigating to a new page with client-side routing, would change the value of the current route, mutating the application state.

When putting these two concepts together, bad things can happen. For example, the user might enter some new data and save it, while we are still persisting something else to the server, causing an inconsistent state.

This is where Redux comes in. Redux attempts to make state Mutations predictable, without losing the performance advantages of Asynchronicity. It does so by imposing certain restrictions on how updates can happen. These restrictions make applications predictable and easy to test.

As a result of these restrictions, Redux also provides a great developer experience. When debugging, you can time travel between previous application states, and pinpoint the exact time when a bug occurs. You can also use this functionality in production—when users report a bug, the whole application state can be transmitted. This means that you can load the exact state of the application when the bug occurred, making reproduction trivial:

The Redux development experience (all state changes are visible, certain actions can be disabled, and the state will be recalculated)

Furthermore, Redux is very simple and uses plain JavaScript objects and functions. As a result, it can run in various different environments, such as a web client (browser), native applications, and even on the server.

To start out, we will cover the basic elements of a Redux application. Afterwards, we will also cover the restrictions mentioned earlier, resulting in the fundamental principles of Redux. Next, we will focus on how to use Redux with React, a library that shares similar principles and is used to generate user interfaces from the data maintained in Redux. Then, we will teach you how to use Redux with Angular, a framework that is also used to generate user interfaces. Next, we will dive deep into how to solve common problems in web development (such as debugging, user authentication, or interfacing with third-party APIs) with Redux:

How Redux and React play together

Finally, we will discuss how to extend Redux by implementing generic solutions that work with all Redux applications. These generic solutions can be distributed as libraries and there are already many of these out there. For example, to implement undo/redo functionality in any application, you simply use a library, and it will work, regardless of how your application is structured.

In this book, we will develop a blog application with Redux. This application will keep getting extended throughout the chapters and help us practice concepts learned in the book.

In this chapter, we will cover:

Defining the state of our application

Defining actions

Tying the state and actions together

Learning about Redux's three fundamental principles

Introducing the Redux ecosystem

Defining the application state

Before we start implementing a Redux application, we first have to think about the application state. The state of a Redux application is simply a JavaScript value (usually an object).

The application state includes all data needed to render the application and handle user actions. Later, we will use parts of the application state to render HTML templates and make API requests.

You might not know the full application state in the beginning; that's fine. We will make sure that we design our application state in an extendable way. In a Redux application, the state is usually represented as a JavaScript object. Each property of the object describes a substate of the application.

For example, a simple blog application state could consist of an array of posts (which are written by the user and contain some text):

{ posts: [ { user: 'dan', text: 'Hello World!' }, { user: 'des', text: 'Welcome to the blog' } ] }

Imagine that we want to add a category string to posts later—we can simply add this property to the objects in the posts array:

{ posts: [ { user: 'dan',

category: 'hello',

text: 'Hello World!' }, { user: 'des',

category: 'welcome',

text: 'Welcome to the blog' } ] }

Now, let's say we want to implement filtering posts by category; we could extend our state object with a filter property that stores the category as a string:

{ posts: [ { user: 'dan', category: 'hello', text: 'Hello World!' }, { user: 'des', category: 'welcome', text: 'Welcome to the blog' } ]

,

filter: 'hello'

}

We can reconstruct the whole application state from this object. Being able to do this is one of the things that makes Redux so awesome.

In a later chapter, we will observe how to add the logic that actually filters posts by making use of the application state.

You might think that the application state will become a very complicated object at some point, and that's true—but in a more advanced project; the state won't be defined in a single file. Application state can be split up and dealt with in multiple files (a separate file for each substate), then combined together.

To keep things simple, let's define our application state as an array of posts for now:

[ { user: 'dan', category: 'hello', text: 'Hello World!' }, { user: 'des', category: 'welcome', text: 'Welcome to the blog' } ]

Defining actions

Now that we have defined the state of our application, we also need a way to change the state. In Redux, we never modify the state directly. To ensure that the application is predictable, only actions can change the state. Redux actions are simply JavaScript objects, with a type property that specifies the name of the action. Let's say we want to create a new post in our blog, we could use an action like this:

{ type: 'CREATE_POST', user: 'dan', text: 'New post' }

Later on, we could define another action for setting the filter:

{ type: 'SET_FILTER', filter: 'hello' }

These action objects can be passed to Redux, resulting in a new state being calculated from the current state and the action. This process is called dispatching an action.

The way state changes are processed in Redux makes them very explicit, clear, and predictable. If you want to find out how a certain state change happened, just look at the action that was dispatched. Furthermore, you can reproduce state changes by reverting and redispatching actions (also known as time traveling).

Redux' three fundamental principles

As mentioned earlier, Redux is based on certain principles and restrictions. The API of Redux is very small and only consists of a handful of functions. These principles and restrictions are what makes Redux so powerful, and you need to stick to them to be able to reap all the benefits of Redux.

We will now discuss the three fundamental principles of Redux:

Single source of truth

Read-only state

State changes are processed with pure functions

Single source of truth

Redux consists of a single store, which is a JavaScript value containing the entire state of your application. A single source of truth comes with a lot of benefits:

In traditional applications, the state is stored in different places across the whole application. With a single source of truth, debugging becomes easy, as you simply have one value to look at.

It is easy to create universal apps, as you can serialize the application state on the server and send it to the client without much effort.

Generalized functionalities, such as undo/redo, become easy to implement. For example, you can simply drop in a library that turns (a part of) your state into an

undoable

state.

To access the application state, Redux provides a .getState() function on the store object. You can view the full state, as follows:

console.log(store.getState())

The output of the preceding code will be the application state. In our example application, the output would be the post array we defined earlier:

[ { user: 'dan', text: 'Hello World!' },