Redux Typescript Concept for Less Boilerplate

Unsignedmind
3 min readNov 8, 2020

Intro

I am new here and new to react and redux. I worked with NgXS in Angular before but that’s it to state management. Please tell me what you think about my approach and what I need to look out for :) Surely there is room for improvement.

GithubRepo

Advantages with this setup

You need a new action that just overrides the state?
Easy! Define the name of the action and 1 call. Overrding is considered default and already implemented for all actions. So you only need 2 lines.

Your action does not override but adds up with the value in the state?
Add function which does that and add it to a map.

New State?
Add the name of that state, definde the state model and add the state to the app state model.

Reducer?
I don’t know what you are talking about :)

Redux Setup

This setup aims to remove as much boilerplate code as possible.

The redux setup consists of the following components:

  • Generated Actions (custom actions possible)
  • State Merger (custom business logic when saving to state)
  • Reducer (1 line reducer)

State

Each state has a name. The names are stored in an enum. All states are part of the App state.

Actions

Generic action creator

This creator is stored in `src/state/utils`. To Create an action you need 4 things:

  • StateModel
  • ActionType Enum
  • Payload
  • Name of the state or boolean

The StateModel & ActionType Enum are stored in the component directory.

Use action generator

The payload is type checked. It has a `Partial<T>` interface of given state model. With the generic creator there are no extra action definitions necessary. Define the attributes which changed in the call.
The constructor of the generic creator has 2 optional parameters. The stateName and a boolean value.

  • useCustomStateMerger(boolean): When the boolean is set to true then the action loads a custom state merger which is intended to hold some business logic added by the developer. Read more about that under State Merger.
  • stateName(StateName): If the useCustomStateMerger flag is false or undefined the default merger is used. The default merger needs to know to which state the payload should be applied to.

Usage

Create custom actions

If the generated actions reach their limitations then self written actions can be added with the template below.

Usage

State Merger

What is this for? It merges the payload with the state. There is a default strategy but custom one are also possible.

Default Merger

Based on the state name provided in the genericAction call the default state merger applies the payload to the correct state. That’s possible because the state name equal the state attribute name in the app state model.

Custom Merger

The generated actions include the reducer, and the action class has a flag named useCustomStateMerger. If true then the reduce function of that action gets a state merger from a map and runs the merge function. By default the payload of the action overwrites the state. But as there could also be some business logic necessary then a custom merger is needed. These are stored in `src/state/state-merger/`.
To create a new state merger first add a new class in the `state-merger` file. They look like this:

Naming & Types

  • The naming default convention is actionNameStateMerger.
  • The class needs to extend the StateMerger base class.
  • Implement the merge function and set the types to the StateModel
  • Payload must be wrapped in `Partial<T>`
  • The return type must be AppStateModel.

Merge

  • make sure to make a copy of the app state itself and a copy of the state you want to update to avoid “Common Mistake #2: Only making a shallow copy of one level”

The class must be added to the map `state-merger-map`afterwards.

Each entry is an array that consists of the ActionType Enum, and a new instance of the state merger class

Reducer

A universal reducer exists for all generated actions. It can also handle the custom actions. Since the logic of the reducer is “outsourced” the original reducer is a one-liner.

Sources

--

--

Unsignedmind
0 Followers

I am a Frontend Dev focused mainly on Angular ecommerce but currently I am giving React and Redux a try. Also my first blog post here ist about Redux.