0.0.3 • Published 6 months ago

react-mobx-local-model v0.0.3

Weekly downloads
-
License
MIT
Repository
-
Last release
6 months ago

The observerWithModel higher-order component (HOC) function allows React components to create local MobX models that can utilize the components' props. This helps to avoid writing excessive boilerplate code and prevents unnecessary re-rendering of components during the synchronization of component props and ReactModel state. observerWithModel is a reimplementation of the official observer hook from the mobx-react-lite package.

Usage

Here's an example of how to use observerWithModel:

import { ReactModel, observerWithModel } from 'react-mobx-local-model';
import { computed } from 'mobx';

// Each local model should extend the `ReactModel` class to create a local model for the component
// with the type arguments that will be used in the component later. The constructor of this kind
// of model shouldn't use any parameters because it will be created automatically like `new TestReactModel()`.
class TestReactModel extends ReactModel<{ name: string }> {
  constructor() {
    super({
      name: computed, // Use the computed decorator to optimize prop access if needed
    });
  }
  get text() {
    // Access the props using the `get` method
    return `Hello ${this.get('name')}`;
  }
}

// The component type will be inferred automatically, e.g., `FC<{ model: TestReactModel, name: string }>`
const Component = observerWithModel(TestReactModel, ({ model, name }) => {
  return (
    <div>
      {name} {model.text}
    </div>
  );
});

In the past, you would need to write a lot of boilerplate code, which could lead to extra re-renders of the Component. Here's how it used to be done:

import React, { useEffect, useMemo } from 'react';
import { observer } from 'mobx-react-lite';
import { makeObservable, observable, runInAction } from 'mobx';

class TestReactModel {
  constructor() {
    makeObservable(this, {
      name: observable,
    });
  }
  name: string;

  get text() {
    return `Hello ${this.name}`;
  }
}

const Component = observer<{ name: string }>(({ name }) => {
  const model = useMemo(() => new TestReactModel());
  useEffect(() => {
    runInAction(() => {
      if (name !== model.name) {
        model.name = name;
      }
    });
  }, [name, model]);

  return (
    <div>
      {name} {model.text}
    </div>
  );
});
0.0.3

6 months ago

0.0.2

6 months ago