Skip to content

Instantly share code, notes, and snippets.

@ajitid
Last active September 13, 2021 20:23
Show Gist options
  • Save ajitid/25cfb9ef4ae81bb91553670100f8f6f7 to your computer and use it in GitHub Desktop.
Save ajitid/25cfb9ef4ae81bb91553670100f8f6f7 to your computer and use it in GitHub Desktop.
React + MobX useObservables

This hook is probably illegal to use. There is a reason why something like this doesn't ship with mobx-react-lite. (See something similar)

Usage

const somestate = useObservables(() =>
  store.getSomeState()
)

const [statex, statey] = useObservables(() => [store.statex, statey])

const justOneState = useObservables(() => store.justOneState)
import { reaction, comparer } from "mobx";
import { useEffect, useRef, useState } from "react";
/**
* A React hook to trigger re-render when a given set of observables change.
*
* Note: This hook is only meant to use inside other hook's definition. If you
* want to use an observable inside a React component or if you want to pass
* observables as arguments to other hooks, use `observer` function or
* `Observer` HOC provided by `mobx-react-lite`.
*
* @param fn A function that returns an observable or an array of observables to
* watch upon
* @returns The return value of `fn`
*/
export const useObservables = <T>(fn: () => T) => {
const fnRef = useRef(fn);
const [, setState] = useState({});
useEffect(
() =>
reaction(fnRef.current, () => setState({}), { equals: comparer.shallow }),
[]
);
return fnRef.current();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment