Skip to content
This repository was archived by the owner on Dec 31, 2020. It is now read-only.
This repository was archived by the owner on Dec 31, 2020. It is now read-only.

[Improvement] useObserver hook #800

Closed
@elderapo

Description

@elderapo

I believe the way mobx-react works with react hooks could be drastically improved. I think a single hook could remove most of the mobx-react-lite API.

The idea is to pass store or any observable to useObservable hook which should return proxied observable object. Then in the proxy get handler we can track "observable accesses" to determine when component should be rerendered. I managed to create a simple proof of concept:

const useObservable = <T extends object>(store: T): T => {
  const forceUpdate = useForceUpdate();

  const reaction = useRef<Reaction | null>(null);
  if (!reaction.current) {
    reaction.current = new Reaction(`useObservable`, () => {
      forceUpdate();
    });
  }

  const dispose = () => {
    if (reaction.current && !reaction.current.isDisposed) {
      reaction.current.dispose();
      reaction.current = null;
    }
  };

  useUnmount(() => {
    dispose();
  });

  const proxiedStore = useMemo(
    () =>
      new Proxy(store, {
        get(target, key: keyof typeof target) {
          let val: unknown;

          if (reaction.current) {
            reaction.current.track(() => {
              val = target[key];
            });
          }

          return val;
        }
      }),
    [store]
  );

  return proxiedStore;
};

It works, however, I don't know much about how mobx works internally so there might be a better way of doing it. As I said this is POC so there are most likely unhandled edge cases and improvements to be made.

I have also created a simple demo for anyone interested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions