Let's Write a Redux Controller for Web Components
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.
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:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK