Search code examples
reactjsreact-hooksmobxnpm-publish

How to package a react component on npm without store


I've been reading articles about how to publish react components to NPM, but I'm confused about the details when the component has a store implemented using a library like mobx. Take a simple example like the component you can see in its entirety here:

const App = () => {
  const store = useLocalStore(() => ({
    data: initialData,
    index: 0,
    addRow() {
      if (this.index < this.data.length) {
        this.data = [...this.data, addData[this.index++]];
      }
    }
  }));

  return useObserver(() => (
    <div className="App">
      <MaterialTable
        columns={columns}
        data={store.data}
        title="Sample Material Table"
      />

      <Button onClick={store.addRow}>Add Row</Button>
    </div>
  ));
};

This example uses MobX, where useObserver and useLocalStore are specific to that library. I personally am choosing to use MobX. Let's say I publish this to NPM and use it in another project that prefers to use some other state management library. I think what I have here is confusing in that scenario, and furthermore I'm not sure it would even work at all--or maybe it would... I don't know.

The question is simple: how should I put this component together in such a way as to work with any state management library?


Solution

  • Let's say you want to use mobx and default react hooks as two different types of state management for your component.

    Solution 1:

    First, make mobx a peer dependency of your library, then structure your package in way that the end-user could use (import) your library like this:

    //for regular (default) usage with hooks
    import myComponent from 'package-name/hooks'
    
    // for mobx version
    import myComponent from 'package-name/mobx'
    

    In any case, you need to separate the usage of different state libraries, and internally try to reuse (share) as much code as possible when creating your library.

    Solution 2:

    Publish two (or maybe even three) different packages under the same npm scope e.g @myLib/mobx and @myLib/hooks and possibly a third package that has the code that is shared between all the packages @myLib/default