What is mobx-react-lite?
mobx-react-lite is a lightweight wrapper around MobX that provides React bindings for functional components. It allows you to use MobX for state management in your React applications with minimal boilerplate and high performance.
What are mobx-react-lite's main functionalities?
Observer Component
The `observer` function is used to create a reactive component that will automatically re-render when the observed state changes. In this example, the `Counter` component re-renders whenever `counter.count` is updated.
import React from 'react';
import { observer } from 'mobx-react-lite';
import { observable } from 'mobx';
const counter = observable({ count: 0 });
const Counter = observer(() => (
<div>
<button onClick={() => counter.count++}>Increment</button>
<p>{counter.count}</p>
</div>
));
export default Counter;
Using MobX stores
This example demonstrates how to use MobX stores with `mobx-react-lite`. The `CounterStore` class is an observable store, and the `Counter` component observes changes to the store and re-renders accordingly.
import React from 'react';
import { observer } from 'mobx-react-lite';
import { observable } from 'mobx';
class CounterStore {
@observable count = 0;
increment() {
this.count++;
}
}
const counterStore = new CounterStore();
const Counter = observer(() => (
<div>
<button onClick={() => counterStore.increment()}>Increment</button>
<p>{counterStore.count}</p>
</div>
));
export default Counter;
Using hooks with MobX
The `useLocalObservable` hook allows you to create local observable state within a functional component. This example shows how to use the hook to create a local counter state and update it within the component.
import React from 'react';
import { observer, useLocalObservable } from 'mobx-react-lite';
const Counter = observer(() => {
const counter = useLocalObservable(() => ({ count: 0, increment() { this.count++; } }));
return (
<div>
<button onClick={counter.increment}>Increment</button>
<p>{counter.count}</p>
</div>
);
});
export default Counter;
Other packages similar to mobx-react-lite
redux
Redux is a popular state management library for JavaScript applications. Unlike MobX, which uses observables and reactive programming, Redux relies on a unidirectional data flow and immutable state updates. Redux is often used with React through the `react-redux` bindings.
recoil
Recoil is a state management library for React that provides a set of utilities for managing state in a more granular and efficient way. It uses atoms and selectors to manage state and derive computed values. Recoil is designed to work seamlessly with React's concurrent mode.
zustand
Zustand is a small, fast, and scalable state management library for React. It uses hooks to manage state and provides a simple API for creating and updating state. Zustand is less opinionated than MobX and can be a good choice for simpler state management needs.
mobx-react-lite
You need React version 16.8.0 and above
This is a lighter version of mobx-react which supports React functional components only and as such makes the library slightly faster and smaller (only 1.5kB gzipped). In fact mobx-react@6
has this library as a dependency and builds on top of it.
The library does not include any Provider/inject utilities as they can be fully replaced with React Context. Check out the migration guide.
Class based components are not supported except using <Observer>
directly in class render
method. If you want to transition existing projects from classes to hooks, use mobx-react 6+.
See more at the libraries overview.
The site contains various examples and recipes for using MobX in React world. Feel free to contribute. The API reference of this package follows 👇.
API reference ⚒
<Observer>{renderFn}</Observer>
(user guide)
Is a React component, which applies observer to an anonymous region in your component.
observer<P>(baseComponent: FunctionComponent<P>, options?: IObserverOptions): FunctionComponent<P>
(user guide)
interface IObserverOptions {
forwardRef?: boolean
}
The observer converts a component into a reactive component, which tracks which observables are used automatically and re-renders the component when one of these values changes.
useObserver<T>(fn: () => T, baseComponentName = "observed", options?: IUseObserverOptions): T
(user guide)
interface IUseObserverOptions {
useForceUpdate: () => () => void
}
It allows you to use an observer like behaviour, but still allowing you to optimize the component in any way you want (e.g. using memo with a custom areEqual, using forwardRef, etc.) and to declare exactly the part that is observed (the render phase).
useLocalStore<T, S>(initializer: () => T, source?: S): T
(user guide)
Local observable state can be introduced by using the useLocalStore hook, that runs its initializer function once to create an observable store and keeps it around for a lifetime of a component.
useAsObservableSource<T>(source: T): T
(user guide)
The useAsObservableSource hook can be used to turn any set of values into an observable object that has a stable reference (the same object is returned every time from the hook).
Observer batching
Note: configuring observer batching is only needed when using mobx-react-lite
2.0.* or 2.1.*. From 2.2 onward it will be configured automatically based on the availability of react-dom / react-native packages
Check out the elaborate explanation.
In short without observer batching the React doesn't guarantee the order component rendering in some cases. We highly recommend that you configure batching to avoid these random surprises.
Import one of these before any React rendering is happening, typically index.js/ts
. For Jest tests you can utilize setupFilesAfterEnv.
React DOM:
import 'mobx-react-lite/batchingForReactDom'
React Native:
import 'mobx-react-lite/batchingForReactNative'
Opt-out
To opt-out from batching in some specific cases, simply import the following to silence the warning.
import 'mobx-react-lite/batchingOptOut'
Custom batched updates
Above imports are for a convenience to utilize standard versions of batching. If you for some reason have customized version of batched updates, you can do the following instead.
import { observerBatching } from "mobx-react-lite"
observerBatching(customBatchedUpdates)