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?
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