зеркало из https://github.com/microsoft/satcheljs.git
Wrap dispatch in a transaction (#106)
For various historical reasons dispatch hasn't been wrapped in `transaction` since an early version of Satchel. This means that every subscriber to an action executes in its own transaction, possibly causing multiple unnecessary renders. Now that we've updated to MobX v4, it's possible to use `transaction` again. The change to actual source code is trivial; the rest of the change is test code to validate that we're handling the transaction correctly.
This commit is contained in:
Родитель
4c09ba38a0
Коммит
028bc0c4be
|
@ -1,3 +1,4 @@
|
|||
import { transaction } from 'mobx';
|
||||
import ActionMessage from './interfaces/ActionMessage';
|
||||
import Subscriber from './interfaces/Subscriber';
|
||||
import { getPrivateActionId } from './actionCreator';
|
||||
|
@ -18,7 +19,10 @@ export function dispatch(actionMessage: ActionMessage) {
|
|||
}
|
||||
|
||||
let dispatchWithMiddleware = getGlobalContext().dispatchWithMiddleware || finalDispatch;
|
||||
dispatchWithMiddleware(actionMessage);
|
||||
|
||||
transaction(() => {
|
||||
dispatchWithMiddleware(actionMessage);
|
||||
});
|
||||
}
|
||||
|
||||
export function finalDispatch(actionMessage: ActionMessage): void | Promise<void> {
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import 'jasmine';
|
||||
import { action } from '../src/actionCreator';
|
||||
import applyMiddleware from '../src/applyMiddleware';
|
||||
import { dispatch } from '../src/dispatcher';
|
||||
import mutator from '../src/mutator';
|
||||
import orchestrator from '../src/orchestrator';
|
||||
import { mutatorAction } from '../src/simpleSubscribers';
|
||||
import createStore from '../src/createStore';
|
||||
import { autorun } from 'mobx';
|
||||
import {
|
||||
action,
|
||||
applyMiddleware,
|
||||
createStore,
|
||||
dispatch,
|
||||
mutator,
|
||||
mutatorAction,
|
||||
orchestrator,
|
||||
} from '../src/index';
|
||||
|
||||
describe('satcheljs', () => {
|
||||
it('mutators subscribe to actions', () => {
|
||||
|
@ -19,7 +22,7 @@ describe('satcheljs', () => {
|
|||
});
|
||||
|
||||
// Create a mutator that subscribes to it
|
||||
let onTestAction = mutator(testAction, function(actionMessage) {
|
||||
mutator(testAction, function(actionMessage) {
|
||||
actualValue = actionMessage.value;
|
||||
});
|
||||
|
||||
|
@ -54,9 +57,10 @@ describe('satcheljs', () => {
|
|||
it('mutators can modify the store', () => {
|
||||
// Arrange
|
||||
let store = createStore('testStore', { testProperty: 'testValue' })();
|
||||
autorun(() => store.testProperty); // strict mode only applies if store is observed
|
||||
let modifyStore = action('modifyStore');
|
||||
|
||||
let onModifyStore = mutator(modifyStore, actionMessage => {
|
||||
mutator(modifyStore, () => {
|
||||
store.testProperty = 'newValue';
|
||||
});
|
||||
|
||||
|
@ -67,6 +71,47 @@ describe('satcheljs', () => {
|
|||
expect(store.testProperty).toBe('newValue');
|
||||
});
|
||||
|
||||
it('orchestrators cannot modify the store', () => {
|
||||
// Arrange
|
||||
let store = createStore('testStore', { testProperty: 'testValue' })();
|
||||
autorun(() => store.testProperty); // strict mode only applies if store is observed
|
||||
let modifyStore = action('modifyStore');
|
||||
|
||||
orchestrator(modifyStore, () => {
|
||||
store.testProperty = 'newValue';
|
||||
});
|
||||
|
||||
// Act / Assert
|
||||
expect(() => {
|
||||
modifyStore();
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('all subscribers are handled in one transaction', () => {
|
||||
// Arrange
|
||||
let store = createStore('testStore', { testProperty: 0 })();
|
||||
let modifyStore = action('modifyStore');
|
||||
|
||||
mutator(modifyStore, () => {
|
||||
store.testProperty++;
|
||||
});
|
||||
|
||||
mutator(modifyStore, () => {
|
||||
store.testProperty++;
|
||||
});
|
||||
|
||||
let values: number[] = [];
|
||||
autorun(() => {
|
||||
values.push(store.testProperty);
|
||||
});
|
||||
|
||||
// Act
|
||||
modifyStore();
|
||||
|
||||
// Assert
|
||||
expect(values).toEqual([0, 2]);
|
||||
});
|
||||
|
||||
it('middleware gets called during dispatch', () => {
|
||||
// Arrange
|
||||
let actualValue;
|
||||
|
|
Загрузка…
Ссылка в новой задаче