DEV Community

mizchi (Kotaro Chikuba)
mizchi (Kotaro Chikuba)

Posted on

redux-workerized - Redux in WebWorker for React and Vue

I made experimental modules to use redux in worker.

mizchi/redux-workerized

  • TypeScript Friendly API
  • Redux.Store in Worker
  • React Hooks API and Vue Plugin

Shared Store example

Code

full code is here https://github.com/mizchi/redux-workerized/tree/master/examples/microfront

import "@babel/polyfill"; import { RootState, increment, Increment, INCREMENT } from "./reducer"; const worker = new Worker("./worker.ts"); // React import React, { useCallback } from "react"; import ReactDOM from "react-dom"; import { createWorkerContext } from "redux-workerize/react"; const { WorkerContext, useSnapshot, useDispatch, ready } = createWorkerContext< RootState, { value: number } >(worker, async (state: RootState) => { return state.counter; }); function CounterApp() { const value = useSnapshot(state => state.value); const dispatch = useDispatch<Increment>(); const onClick = useCallback(() => { dispatch(increment()); }, []); return <button onClick={onClick}>{value}</button>; } ready.then(() => { ReactDOM.render( <WorkerContext> <CounterApp /> </WorkerContext>,  document.querySelector(".react-root") ); }); // Vue import Vue from "vue"; import Vuex from "vuex"; import App from "./App.vue"; import { workerPlugin, proxy, SYNC } from "redux-workerize/vue"; Vue.use(Vuex); type CounterSnapshot = { value: number; }; export type State = { remote: CounterSnapshot; }; const store = new Vuex.Store<State>({ state: { remote: { value: 0 } }, mutations: { [SYNC](state, payload: CounterSnapshot) { state.remote = { ...state.remote, ...payload }; }, ...proxy([INCREMENT]) }, plugins: [ workerPlugin( worker, (state: RootState): CounterSnapshot => { return state.counter; } ) ] }); new Vue({ store, el: ".vue-root", render(h) { return h(App); } }); 
Enter fullscreen mode Exit fullscreen mode

NOTE: You need react@16.7.0-alpha.0 react-dom@16.7.0-alpha.0

Vuex subscribe remote Redux.Store snapshot

Worker Side

import * as Comlink from "comlinkjs"; import { createStore } from "redux"; import reducer from "./reducer"; import { createWorkerizedStore } from "redux-workerized/worker"; const store = createStore(reducer); const storeAPI = createWorkerizedStore(store); Comlink.expose({ ...storeAPI }, self); 
Enter fullscreen mode Exit fullscreen mode

What I want to do

  • For performance by off-the-main-thread
  • Store in Woker is training wheels to write universal javascript.

Top comments (0)