10

Let's Write a Redux Controller for Web Components

 2 years ago
source link: https://dev.to/bennypowers/lets-write-a-redux-controller-for-web-components-4edl
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Elliott Marquez challenged me to write a redux controller on the Lit & Friends slack.

So let's get cracking!

Step 0: The Setup

First step let's make a new project and import some dependencies to help us develop.

mkdir controllers
cd controllers
git init
npm init --yes
npm i -D typescript lit
touch reducer.ts

Enter fullscreen mode

Exit fullscreen mode

Ok next we'll set up the controller class in reducer.ts

import type { ReactiveController, ReactiveControllerHost } from 'lit';

export class ReducerController implements ReactiveController {
  constructor(
    public host: ReactiveControllerHost,
  ) {
    host.addController(this);
  }

  hostUpdate()?: void;
}

Enter fullscreen mode

Exit fullscreen mode

That hostUpdate signature is just to keep typescript from complaining. 🤷.

Step 1: Reducers

Our controller essentially bolts some statefullness onto a function which takes some state T and some action A and returns some other or the same state T. So let's formalize that:

type Reducer<T, A> = (state: T, action: A) => T;

Enter fullscreen mode

Exit fullscreen mode

The controller should take that reducer, along with some initial state, and pin them to the class instance.

export class ReducerController<T = unknown, A = unknown> implements ReactiveController {
  public state: T;

  constructor(
    private host: ReactiveControllerHost,
    public reducer: Reducer<T, A>,
    public initialState: T,
  ) {
    this.host.addController(this);
    this.state = initialState;
  }

  hostUpdate?():void
}

Enter fullscreen mode

Exit fullscreen mode

Step 2: Actions

Believe it or not we're pretty much done. The last piece we need is to implement a dispatch method which takes an action A and updates the host.

dispatch(action: A): void {
  this.state = this.reducer(this.state, action);
  this.host.requestUpdate();
}

Enter fullscreen mode

Exit fullscreen mode

And, as Chef John would say, that's it!

If we want to use our controller, we just create it on a compatible host (like LitElement) and we're off to the races:

Live Demo


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK