pawjs icon indicating copy to clipboard operation
pawjs copied to clipboard

Support for Recoil.js

Open joseananio opened this issue 4 years ago • 0 comments

Any chance recoil will be supported? It has relatively simpler interface than redux so I expect a plugin to be easy to whip up.

I have tried unsuccessfully to adapt the pawjs-redux plugin with this error:

A Server error has occurred
Error Stack:
This component must be used inside a <RecoilRoot> component.


Error: This component must be used inside a <RecoilRoot> component.
    at Object.notInAContext (webpack-internal:///./node_modules/recoil/es/recoil.js:1546:9)
    at getRecoilValueAsLoadable (webpack-internal:///./node_modules/recoil/es/recoil.js:1312:2315)
    at useRecoilValueLoadable_LEGACY (webpack-internal:///./node_modules/recoil/es/recoil.js:2554:10)
    at useRecoilValueLoadable (webpack-internal:///./node_modules/recoil/es/recoil.js:2568:12)
    at useRecoilValue (webpack-internal:///./node_modules/recoil/es/recoil.js:2586:18)
    at useRecoilState (webpack-internal:///./node_modules/recoil/es/recoil.js:2638:11)
    at TT (webpack-internal:///./src/components/auth/register.js:39:64)
    at renderWithHooks (webpack-internal:///./node_modules/@hot-loader/react-dom/cjs/react-dom.development.js:14804:14)
    at mountIndeterminateComponent (webpack-internal:///./node_modules/@hot-loader/react-dom/cjs/react-dom.development.js:17483:7)
    at beginWork (webpack-internal:///./node_modules/@hot-loader/react-dom/cjs/react-dom.development.js:18597:8)


Component Stack:

    in TT (created by Context.Consumer)
    in _default
    in ErrorBoundary
    in Unknown (created by Context.Consumer)
    in withRouter() (created by Context.Consumer)
    in Route
    in Switch
    in ErrorBoundary
    in App (created by HotExportedApp)
    in AppContainer (created by HotExportedApp)
    in HotExportedApp
    in RecoilRoot
    in Router
    in ErrorBoundary

Here's my client.js in the plugin:

export default class RecoilClient {
  constructor() {
    this.hooks = {
      recoilInit: new AsyncSeriesHook(["state"]),
    };
  }

  apply(clientHandler) {
    clientHandler.hooks.beforeLoadData.tapPromise(
      "AddRecoilProvider",
      async (setParams, getParams) => {
        const state = {
          setInitialState: (iState) => {
            // initialState = cloneDeep(iState);
          },
          getInitialState: () => {
            // if (typeof initialState === 'undefined') return {};
            // return cloneDeep(initialState);
            return {};
          },
        };
        await new Promise((r) => this.hooks.recoilInit.callAsync(state, r));
      }
    );

    clientHandler.hooks.beforeRender.tapPromise(
      "AddRecoilProvider",
      async (app) => {
        // eslint-disable-next-line
        app.children = <RecoilRoot>{app.children}</RecoilRoot>;
      }
    );
  }
}

It works when I add the recoil package directly to pawjs like below so I believe the issue is with plugin handling

// src/client/handler.tsx
...
const children = (
      // eslint-disable-next-line react/jsx-props-no-spreading
      <components.appRouter basename={this.options.env.appRootUrl} {...routerParams}>
        <RecoilRoot>{appRoutes.renderedRoutes}</RecoilRoot>
      </components.appRouter>
    );
...

joseananio avatar Dec 24 '20 08:12 joseananio