overmind
overmind copied to clipboard
Feature: Use overmind for isolated feature development
First of all, thanks for creating and maintaining Overmind.
We're happy users of it and we like the concepts and excellent Typescript support but as our application grows we find more and more use cases when we don't want to keep the state in a global store and we switch to using React.Context + hooks for isolated feature development, so we can even pack the feature as an NPM package at some point and reuse it between several applications.
Switching between the local state with hooks and the global store with Overmind has a cognitive overhead since the concepts are different. When we realize that it's better to keep some particular state locally, or globally, moving an implementation from local to global, or from global to local requires a substantial refactoring.
It would be nice if we could use Overmind for local feature development, so moving actions, states, reactions, and effects between local and global is just a matter of moving code blocks.
Something similar to useLocalStore in Mobx would be extremely useful in this case. An ability to create a local instance without a lot of boilerplate would encourage to start with a local store and move things to a global one if when necessary.
import { createLocalOvermind } from 'overmind-react'
const [ MyFeatureProvider, useMyLocalFeature ] = createLocalOvermind('my-unique-feature-id', (initialState) => {
return {
actions: {
setFoo({ state }, value) {
state.foo = value;
}
},
state: {
foo: initialState.foo
},
effects: {},
onInitialize: function () {},
// this is called when Provider is remove from React tree
onDispose: function () {}
};
})
export { MyFeatureProvider, useMyLocalFeature };
const Container = () => {
return (
<MyFeatureProvider foo="bar">
<ChildComponent />
</MyFeatureProvider>
);
}
const ChildComponent = () => {
const feature = useMyLocalFeature();
return (
<div>
<button onClick={() => { feature.actions.setFoo('batman')}}>change</button>
<span>{feature.state.foo}</span>
</div>
);
};