/react-worker-components

React Worker Components simplify using Web Workers

Primary LanguageTypeScriptMIT LicenseMIT

react-worker-components

CI npm size

React Worker Components simplify using Web Workers

Introduction

This is an experimental project inspired by React Server Component.

I've been developing several libraries to interact with Web Workers.

RSC style would be pertty useful for Web Workers. RWC is the same idea for Web Workers. It tries to reproduce the similar behavior as possible. Please try the examples. Feedbacks are welcome.

Install

npm install react-worker-components

Usage

TextBox.js

This is a component that can be used in the RWC tree. regsiter is important to enable serialization.

import React, { useState } from 'react';

import { register } from 'react-worker-components';

export const TextBox = () => {
  const [text, setText] = useState('');
  return (
    <div>
      <span>Text: {text}</span>
      <input value={text} onChange={(event) => setText(event.target.value)} />
    </div>
  );
};

register(TextBox, 'TextBox');

Hello.worker.js

This is a component that runs only on web workers. expose is necessary to communicate with the main thread.

import React from 'react';

import { expose } from 'react-worker-components';

import { TextBox } from './TextBox';

const fib = (i) => (i <= 1 ? i : fib(i - 1) + fib(i - 2));

const Hello = ({ count, children }) => {
  const fibNum = fib(count);
  return (
    <div>
      <div>Hello from worker: {fibNum}</div>
      <h1>Main TextBox</h1>
      {children}
      <h1>Worker TextBox</h1>
      <TextBox />
    </div>
  );
};

expose(Hello);

App.js

This is the entry point component in the main thread. wrap is to communicate with the worker thread.

import React, { Suspense, useState } from 'react';

import { wrap } from 'react-worker-components';

import { TextBox } from './TextBox';

const Hello = wrap(() => new Worker('./Hello.worker', { type: 'module' }));

export const App = () => {
  const [count, setCount] = useState(1);
  return (
    <div>
      <span>Count: {count}</span>
      <button type="button" onClick={() => setCount(count + 1)}>+1</button>
      <button type="button" onClick={() => setCount((c) => c - 1)}>-1</button>
      <Suspense fallback="Loading...">
        <Hello count={count}>
          <TextBox />
        </Hello>
      </Suspense>
    </div>
  );
};

API

TODO

Examples

The examples folder contains working examples. You can run one of them with

PORT=8080 npm run examples:01_minimal

and open http://localhost:8080 in your web browser.