UNPKG

1.74 kBJavaScriptView Raw
1import { computed, _isComputingDerivation } from "mobx";
2/**
3 *`expr` can be used to create temporary computed values inside computed values.
4 * Nesting computed values is useful to create cheap computations in order to prevent expensive computations from needing to run.
5 * In the following example the expression prevents that a component is rerender _each time_ the selection changes;
6 * instead it will only rerenders when the current todo is (de)selected.
7 *
8 * `expr(func)` is an alias for `computed(func).get()`.
9 * Please note that the function given to `expr` is evaluated _twice_ in the scenario that the overall expression value changes.
10 * It is evaluated the first time when any observables it depends on change.
11 * It is evaluated a second time when a change in its value triggers the outer computed or reaction to evaluate, which recreates and reevaluates the expression.
12 *
13 * In the following example, the expression prevents the `TodoView` component from being re-rendered if the selection changes elsewhere.
14 * Instead, the component will only re-render when the relevant todo is (de)selected, which happens much less frequently.
15 *
16 * @example
17 * const TodoView = observer(({ todo, editorState }) => {
18 * const isSelected = mobxUtils.expr(() => editorState.selection === todo)
19 * return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
20 * })
21 */
22export function expr(expr) {
23 if (!_isComputingDerivation())
24 console.warn("'expr' should only be used inside other reactive functions.");
25 // optimization: would be more efficient if the expr itself wouldn't be evaluated first on the next change, but just a 'changed' signal would be fired
26 return computed(expr).get();
27}