Reaction

用法: reaction(() => data, data => { sideEffect }, fireImmediately = false, delay = 0).

它是一个提供了细粒度控制追踪哪些 observables 的 autorun 变种。 它接收两个函数, 第一个是用来追踪并返回数据并作为第二个方法的输入的副作用。 不同于 autorun, 当其创建时副作用不会直接运行,只有在数据表达式首次返回一个新值后才会运行。 在执行副作用时访问的任何 observable 都不会被追踪。 这个副作用是可以去抖的,就像 autorunAsyncreaction 返回一个清理事务函数。 如果传给 reaction 的第一个参数是字符串, 它将被用来作为调试名称。 传入 reaction 的函数 调用时会接收一个参数,即当前的 reaction,可以用来在执行期间进行清理事务。

值得注意的是副作用 对数据表达式中 访问 的数据作出响应,这可能会比实际在效果函数使用的数据要少。 当然, 副作用只会在表达式返回的数据发生更改时触发(修饰符 asStructure 可用于比较深的执行)。 换句话说: reactio 需要你生产副作用中所需要的东西。

在下面的示例中,reaction1reaction2autorun1 都会对 todos 数组中的 todo 的添加、删除或替换作出响应。 但只有 reaction2autorun 会对某个 todotitle 变化作出响应,因为在 reaction2 的数据表达式中使用了 title,而 reaction1 的数据表达式没有使用。 autorun 追踪完整的副作用,因此它将始终正确触发,但也更容易意外地访问相关数据。更多资料查看: what will MobX React to?.

const todos = observable([
    {
        title: "Make coffee",
        done: true,
    },
    {
        title: "Find biscuit",
        done: false
    }
]);

// wrong use of reaction: reacts to length changes, but not to title changes!
const reaction1 = reaction(
    () => todos.length,
    length => console.log("reaction 1:", todos.map(todo => todo.title).join(", "))
);

// correct use of reaction: reacts to length and title changes
const reaction2 = reaction(
    () => todos.map(todo => todo.title),
    titles => console.log("reaction 2:", titles.join(", "))
);

// autorun reacts to just everything that is used in it's function
const autorun1 = autorun(
    () => console.log("autorun 1:", todos.map(todo => todo.title).join(", "))
);

todos.push({ title: "explain reactions", done: false });
// prints:
// reaction 1: Make coffee, find biscuit, explain reactions
// reaction 2: Make coffee, find biscuit, explain reactions
// autorun 1: Make coffee, find biscuit, explain reactions

todos[0].title = "Make tea"
// prints:
// reaction 2: Make tea, find biscuit, explain reactions
// autorun 1: Make tea, find biscuit, explain reactions

Reaction 大致来讲其是 computed(expression).observe(action(sideEffect))autorun(() => action(sideEffect)(expression) 的语法糖。