redux-worker-react

Run a Redux store in a Web Worker

Usage no npm install needed!

<script type="module">
  import reduxWorkerReact from 'https://cdn.skypack.dev/redux-worker-react';
</script>

README

redux-worker-react

在react里将redux运行在worker线程中, 基于 comlink@latset api编写.

  • hooks: 提供函数组件中使用 useDispatch, useSelector, useStore

  • context: 提供单独引入在class中使用情况 StateContext\StoreContext

  • 核心Api,具体参看例子 createProxyStore\expose\getProvider

Why?

如果您在[Redux]中执行任何计算开销很大、频率很高的工作(https://redux.js.org),它可以阻塞UI在运行时做出响应。

理论上讲,webworkers应该是完美的解决方案:您可以在worker线程中完成繁重的工作,而不会干扰主UI线程。但基于消息的 web worker API把我们带到陌生的地方。

这个库旨在使开发人员使用基于worker的Redux存储的体验尽可能类似于普通的Redux使用上。

How it works

这个库为您提供了一个代理Redux store。对于您的应用程序,代理看起来就像真实的一样:您可以使用useDispatchuseSelector与它同步通信,就像官方的[rect redux]那样(https://github.com/reduxjs/react-redux)绑定提供

diagram

运用google comlink api中间层编写Comlink

Usage

  1. 建立worker文件
   // redux.worker.ts 
  import { createProxyStore, expose } from 'redux-worker-react';
  import store from '.';

  const proxyStore = createProxyStore(store());
  // eslint-disable-next-line no-restricted-globals
  const ctx: Worker = self as any; // 创建主进程this指针
  expose(proxyStore, ctx);

  export default null as any;
  1. 任何ts或tsx文件使用
// App.tsx
import { getProvider } from 'redux-worker-react';
import ReduxInWorker from './store/redux.worker';
import { WithWorker } from './WithWorker';

const worker = new ReduxInWorker();
const ProxyProvider = getProvider(worker);

const App = () => (
  <div className={styled.div}>
    <div style={{display: 'flex'}}>
      {/* using redux-workerized */}
      <ProxyProvider>
        <WithWorker />
      </ProxyProvider>
    </div>
  </div>
);
  1. 获取最新store中的state和dispatch触发action
import * as React from 'react';
import { useDispatch, useSelector } from 'redux-worker-react'; // 重点
import { Calculate } from 'src/components/Calculate';
import { State } from './store/reducer';

export function WithWorker() {
  const state = useSelector((s: State) => s); // 重点
  const dispatch = useDispatch(); // 重点

  return (
    <div>
      <h2>With worker</h2>
      <Calculate state={state} dispatch={dispatch} />
    </div>
  );
}
  1. webpack还需配置如下, 下面的wp5, 之前按照相应的语法配置下即可
{
  // ...
  worker: {
    test: /\.worker\.ts$/i,
    exclude: /node_modules/,
    use: {
      worker: {
        loader: 'worker-loader',
        options: {
          filename: '[name].[chunkhash:8].js',
        },
      },
    },
  },
  // ...
}

Add the dependency

yarn add redux-worker-react

Prior art