mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] store: prevent changes to store state in useStore return value
closes #500
This commit is contained in:
@@ -274,6 +274,9 @@ Note that if the selector function returns a primitive type, the result of
|
|||||||
is important to define the `onUpdate` option to properly update the value
|
is important to define the `onUpdate` option to properly update the value
|
||||||
manually when it changes.
|
manually when it changes.
|
||||||
|
|
||||||
|
Also, the return value from `useStore` is not supposed to be modified. The store
|
||||||
|
state should only be updated with actions.
|
||||||
|
|
||||||
### `useDispatch`
|
### `useDispatch`
|
||||||
|
|
||||||
The `useDispatch` hook is useful when a component needs to be able to dispatch
|
The `useDispatch` hook is useful when a component needs to be able to dispatch
|
||||||
|
|||||||
+1
-2
@@ -134,8 +134,7 @@ export function useStore(selector, options: SelectorOptions = {}): any {
|
|||||||
return result[k];
|
return result[k];
|
||||||
},
|
},
|
||||||
set(target, k, v) {
|
set(target, k, v) {
|
||||||
result[k] = v;
|
throw new Error("Store state should only be modified through actions");
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,24 @@ describe("connecting a component to store", () => {
|
|||||||
expect(error.message).toBe("No store found when connecting 'App'");
|
expect(error.message).toBe("No store found when connecting 'App'");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("cannot modify state returned by usestore", async () => {
|
||||||
|
const state = { a: { b: 1 } };
|
||||||
|
const actions = {};
|
||||||
|
const store = new Store({ state, actions });
|
||||||
|
|
||||||
|
class App extends Component<any, any> {
|
||||||
|
static template = xml`<div/>`;
|
||||||
|
storeState = useStore(state => state.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
(<any>env).store = store;
|
||||||
|
const app = new App();
|
||||||
|
expect(app.storeState.b).toBe(1);
|
||||||
|
expect(() => (app.storeState.b = 2)).toThrow(
|
||||||
|
"Store state should only be modified through actions"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("can use useStore twice in a component", async () => {
|
test("can use useStore twice in a component", async () => {
|
||||||
const state = { a: 1, b: 2 };
|
const state = { a: 1, b: 2 };
|
||||||
const actions = {
|
const actions = {
|
||||||
|
|||||||
Reference in New Issue
Block a user