Need help with mobx-react-lite?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

mobxjs
2.0K Stars 98 Forks MIT License 480 Commits 0 Opened issues

Description

Lightweight React bindings for MobX based on React 16.8 and Hooks

Services available

!
?

Need anything else?

Contributors list

mobx-react-lite


🚨🚨🚨 This repo has been moved to mobx


CircleCICoverage StatusNPM downloadsMinzipped size

TypeScriptcode style: prettier

Discuss on Github View changelog

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). Note however that it is possible to use

 inside the render of class components.
Unlike 
mobx-react
, it doesn't
Provider
/
inject
, as
useContext
can be used instead.

Compatibility table (major versions)

| mobx | mobx-react-lite | Browser | | ---- | --------------- | ---------------------------------------------- | | 6 | 3 | Modern browsers (IE 11+ in compatibility mode) | | 5 | 2 | Modern browsers | | 4 | 2 | IE 11+, RN w/o Proxy support |

mobx-react-lite
requires React 16.8 or higher.

User Guide 👉 https://mobx.js.org/react-integration.html


API reference ⚒

observer

(baseComponent: FunctionComponent

): FunctionComponent

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. Can only be used for function components. For class component support see the

mobx-react
package.

{renderFn}

Is a React component, which applies observer to an anonymous region in your component.

 can be used both inside class and function components.

useLocalObservable(initializer: () => T, annotations?: AnnotationsMap): T

Creates an observable object with the given properties, methods and computed values.

Note that computed values cannot directly depend on non-observable values, but only on observable values, so it might be needed to sync properties into the observable using

useEffect
(see the example below at
useAsObservableSource
).

useLocalObservable
is a short-hand for:

const [state] = useState(() => observable(initializer(), annotations, { autoBind: true }))

enableStaticRendering(enable: true)

Call

enableStaticRendering(true)
when running in an SSR environment, in which
observer
wrapped components should never re-render, but cleanup after the first rendering automatically. Use
isUsingStaticRendering()
to inspect the current setting.

Deprecated APIs

useObserver(fn: () => T, baseComponentName = "observed", options?: IUseObserverOptions): T
(deprecated)

This API is deprecated in 3.*. It is often used wrong (e.g. to select data rather than for rendering, and

better decouples the rendering from the component updates

interface IUseObserverOptions {
    // optional custom hook that should make a component re-render (or not) upon changes
    // Supported in 2.x only
    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(initializer: () => T, source?: S): T
(deprecated)

This API is deprecated in 3.*. Use

useLocalObservable
instead. They do roughly the same, but
useLocalObservable
accepts an set of annotations as second argument, rather than a
source
object. Using
source
is not recommended, see the deprecation message at
useAsObservableSource
for details

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.

The annotations are similar to the annotations that are passed in to MobX's

observable
API, and can be used to override the automatic member inference of specific fields.

useAsObservableSource(source: T): T
(deprecated)

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).

This API is deprecated in 3.* as it relies on observables to be updated during rendering which is an anti-pattern. Instead, use

useEffect
to synchronize non-observable values with values. Example:

// Before:
function Measurement({ unit }) {
    const observableProps = useAsObservableSource({ unit })
    const state = useLocalStore(() => ({
        length: 0,
        get lengthWithUnit() {
            // lengthWithUnit can only depend on observables, hence the above conversion with `useAsObservableSource`
            return observableProps.unit === "inch"
                ? `${this.length * 2.54} inch`
                : `${this.length} cm`
        }
    }))

return <h1>{state.lengthWithUnit}</h1>

}

// After: function Measurement({ unit }) { const state = useLocalObservable(() => ({ unit, // the initial unit length: 0, get lengthWithUnit() { // lengthWithUnit can only depend on observables, hence the above conversion with useAsObservableSource return this.unit === "inch" ? ${this.length * 2.54} inch : ${this.length} cm } }))

useEffect(() =&gt; {
    // sync the unit from 'props' into the observable 'state'
    state.unit = unit
}, [unit])

return <h1>{state.lengthWithUnit}</h1>

}

Note that, at your own risk, it is also possible to not use

useEffect
, but do
state.unit = unit
instead in the rendering. This is closer to the old behavior, but React will warn correctly about this if this would affect the rendering of other components.

Observer batching (deprecated)

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)

Testing

Running the full test suite now requires node 14+ But the library itself does not have this limitation

In order to avoid memory leaks due to aborted renders from React fiber handling or React

StrictMode
, on environments that does not support FinalizationRegistry, this library needs to run timers to tidy up the remains of the aborted renders.

This can cause issues with test frameworks such as Jest which require that timers be cleaned up before the tests can exit.

clearTimers()

Call

clearTimers()
in the
afterEach
of your tests to ensure that
mobx-react-lite
cleans up immediately and allows tests to exit.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.