Skip to content

Instantly share code, notes, and snippets.

@joenoon
Last active March 25, 2019 08:27
Show Gist options
  • Save joenoon/abafacb23329e535a459ac037f27a05e to your computer and use it in GitHub Desktop.
Save joenoon/abafacb23329e535a459ac037f27a05e to your computer and use it in GitHub Desktop.
Simplified pattern for using mobx-react-lite with less room for error
import {useComputed, useObservable, useObserver as useObserverInternal} from 'mobx-react-lite';
const HOOKS = {
useComputed,
useObservable,
};
export type MobxReactLiteHooks = typeof HOOKS;
// This is for my convenience, not neccessary for the pattern.
export * from 'mobx';
/**
* Any functional component needing observability or using useObservable/useComputed
* should be defined similar to:
*
* ```
* export const MyComponent: React.FunctionComponent<{}> = props =>
* useObserver(function useHooks({useObservable, useComputed}) {
* const someObservable = useObservable({foo: 10});
*
* const myComputedVal = useComputed(() => {
* return someObservable.foo + 10;
* });
*
* return (
* <div>
* MyComponent: {myComputedVal}
* <button onClick={() => (someObservable.foo += 10)}>Bump</button>
* </div>
* );
* });
* ```
*
* Enforcing this pattern and requiring `'useObservable` and `useComputed` are provided
* by a `useObserver` helps ensure expected behavior and the inner `useHooks` named
* function enables properly linting the rules of hooks.
*
* Note: `observer` HOC and the `Observer` component are not exposed. Components can be
* broken down into smaller units that can use `useObserver` with what React already
* provides us, simplifying the usage.
*/
export function useObserver<T>(func: (hooks: MobxReactLiteHooks) => T, baseComponentName?: string): T {
return useObserverInternal(() => func(HOOKS), baseComponentName);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment