Match-id-caaaaddbbc27d8d6fc7beb95bf9fc050a8f86051
This commit is contained in:
parent
93f529b55e
commit
072ceecd13
|
@ -25,7 +25,7 @@ import {
|
|||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
useDebugValue
|
||||
useDebugValue,
|
||||
} from './src/renderer/hooks/HookExternal';
|
||||
import { asyncUpdates } from './src/renderer/TreeBuilder';
|
||||
import { callRenderQueueImmediate } from './src/renderer/taskExecutor/RenderQueue';
|
||||
|
@ -86,7 +86,7 @@ const Horizon = {
|
|||
useStore,
|
||||
clearStore,
|
||||
reduxAdapter,
|
||||
watch
|
||||
watch,
|
||||
};
|
||||
|
||||
export const version = __VERSION__;
|
||||
|
@ -127,7 +127,7 @@ export {
|
|||
useStore,
|
||||
clearStore,
|
||||
reduxAdapter,
|
||||
watch
|
||||
watch,
|
||||
};
|
||||
|
||||
export default Horizon;
|
||||
|
|
|
@ -7,7 +7,6 @@ import { launchUpdateFromVNode } from '../../renderer/TreeBuilder';
|
|||
import { getProcessingVNode } from '../../renderer/GlobalVar';
|
||||
import { VNode } from '../../renderer/vnode/VNode';
|
||||
export interface IObserver {
|
||||
|
||||
useProp: (key: string) => void;
|
||||
|
||||
addListener: (listener: () => void) => void;
|
||||
|
@ -21,19 +20,18 @@ export interface IObserver {
|
|||
triggerUpdate: (vNode: any) => void;
|
||||
|
||||
allChange: () => void;
|
||||
|
||||
|
||||
clearByVNode: (vNode: any) => void;
|
||||
}
|
||||
|
||||
export class Observer implements IObserver {
|
||||
|
||||
vNodeKeys = new WeakMap();
|
||||
|
||||
keyVNodes = new Map();
|
||||
|
||||
listeners:(()=>void)[] = [];
|
||||
listeners: (() => void)[] = [];
|
||||
|
||||
watchers={} as {[key:string]:((key:string, oldValue:any, newValue:any)=>void)[]}
|
||||
watchers = {} as { [key: string]: ((key: string, oldValue: any, newValue: any) => void)[] };
|
||||
|
||||
useProp(key: string | symbol): void {
|
||||
const processingVNode = getProcessingVNode();
|
||||
|
|
|
@ -12,18 +12,18 @@ export function createArrayProxy(rawObj: any[]): any[] {
|
|||
}
|
||||
|
||||
function get(rawObj: any[], key: string, receiver: any) {
|
||||
if (key === 'watch'){
|
||||
if (key === 'watch') {
|
||||
const observer = getObserver(rawObj);
|
||||
|
||||
return (prop:any, handler:(key:string, oldValue:any, newValue:any)=>void)=>{
|
||||
if(!observer.watchers[prop]){
|
||||
observer.watchers[prop]=[] as ((key:string, oldValue:any, newValue:any)=>void)[];
|
||||
return (prop: any, handler: (key: string, oldValue: any, newValue: any) => void) => {
|
||||
if (!observer.watchers[prop]) {
|
||||
observer.watchers[prop] = [] as ((key: string, oldValue: any, newValue: any) => void)[];
|
||||
}
|
||||
observer.watchers[prop].push(handler);
|
||||
return ()=>{
|
||||
observer.watchers[prop]=observer.watchers[prop].filter(cb=>cb!==handler);
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
observer.watchers[prop] = observer.watchers[prop].filter(cb => cb !== handler);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
if (isValidIntegerKey(key) || key === 'length') {
|
||||
|
@ -43,7 +43,7 @@ function set(rawObj: any[], key: string, value: any, receiver: any) {
|
|||
const observer = getObserver(rawObj);
|
||||
|
||||
if (!isSame(newValue, oldValue)) {
|
||||
if(observer.watchers?.[key]){
|
||||
if (observer.watchers?.[key]) {
|
||||
observer.watchers[key].forEach(cb => {
|
||||
cb(key, oldValue, newValue);
|
||||
});
|
||||
|
|
|
@ -34,18 +34,18 @@ function get(rawObj: { size: number }, key: any, receiver: any): any {
|
|||
} else if (Object.prototype.hasOwnProperty.call(handler, key)) {
|
||||
const value = Reflect.get(handler, key, receiver);
|
||||
return value.bind(null, rawObj);
|
||||
} else if (key === 'watch'){
|
||||
} else if (key === 'watch') {
|
||||
const observer = getObserver(rawObj);
|
||||
|
||||
return (prop:any, handler:(key:string, oldValue:any, newValue:any)=>void)=>{
|
||||
if(!observer.watchers[prop]){
|
||||
observer.watchers[prop]=[] as ((key:string, oldValue:any, newValue:any)=>void)[];
|
||||
return (prop: any, handler: (key: string, oldValue: any, newValue: any) => void) => {
|
||||
if (!observer.watchers[prop]) {
|
||||
observer.watchers[prop] = [] as ((key: string, oldValue: any, newValue: any) => void)[];
|
||||
}
|
||||
observer.watchers[prop].push(handler);
|
||||
return ()=>{
|
||||
observer.watchers[prop]=observer.watchers[prop].filter(cb=>cb!==handler);
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
observer.watchers[prop] = observer.watchers[prop].filter(cb => cb !== handler);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
return Reflect.get(rawObj, key, receiver);
|
||||
|
@ -79,7 +79,7 @@ function set(
|
|||
}
|
||||
|
||||
if (valChange) {
|
||||
if(observer.watchers?.[key]){
|
||||
if (observer.watchers?.[key]) {
|
||||
observer.watchers[key].forEach(cb => {
|
||||
cb(key, oldValue, newValue);
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
export function watch(stateVariable:any,listener:(state:any)=>void){
|
||||
listener = listener.bind(null,stateVariable);
|
||||
stateVariable.addListener(listener);
|
||||
export function watch(stateVariable: any, listener: (state: any) => void) {
|
||||
listener = listener.bind(null, stateVariable);
|
||||
stateVariable.addListener(listener);
|
||||
|
||||
return ()=>{
|
||||
stateVariable.removeListener(listener);
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
stateVariable.removeListener(listener);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -35,9 +35,7 @@ type StoreHandler<S extends object, A extends UserActions<S>, C extends UserComp
|
|||
$queue: QueuedStoreActions<S, A>;
|
||||
$a: StoreActions<S, A>;
|
||||
$c: UserComputedValues<S>;
|
||||
} & { [K in keyof S]: S[K] } &
|
||||
{ [K in keyof A]: Action<A[K], S> } &
|
||||
{ [K in keyof C]: ReturnType<C[K]> };
|
||||
} & { [K in keyof S]: S[K] } & { [K in keyof A]: Action<A[K], S> } & { [K in keyof C]: ReturnType<C[K]> };
|
||||
|
||||
type PlannedAction<S extends object, F extends ActionFunction<S>> = {
|
||||
action: string;
|
||||
|
@ -103,7 +101,7 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
|
|||
const $a: Partial<StoreActions<S, A>> = {};
|
||||
const $queue: Partial<StoreActions<S, A>> = {};
|
||||
const $c: Partial<ComputedValues<S, C>> = {};
|
||||
const handler = ({
|
||||
const handler = {
|
||||
$subscribe,
|
||||
$unsubscribe,
|
||||
$a: $a as StoreActions<S, A>,
|
||||
|
@ -111,7 +109,7 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
|
|||
$c: $c as ComputedValues<S, C>,
|
||||
$config: config,
|
||||
$queue: $queue as QueuedStoreActions<S, A>,
|
||||
} as unknown) as StoreHandler<S, A, C>;
|
||||
} as unknown as StoreHandler<S, A, C>;
|
||||
|
||||
function tryNextAction() {
|
||||
if (!plannedActions.length) {
|
||||
|
@ -205,7 +203,7 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
|
|||
}
|
||||
|
||||
export function clearVNodeObservers(vNode) {
|
||||
if(!vNode.observers) return;
|
||||
if (!vNode.observers) return;
|
||||
vNode.observers.forEach(observer => {
|
||||
observer.clearByVNode(vNode);
|
||||
});
|
||||
|
@ -220,14 +218,14 @@ function hookStore() {
|
|||
if (!processingVNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!processingVNode.observers) {
|
||||
processingVNode.observers = new Set<Observer>();
|
||||
}
|
||||
|
||||
if (processingVNode.tag === FunctionComponent) {
|
||||
// from FunctionComponent
|
||||
const vNodeRef = (useRef(null) as unknown) as { current: VNode };
|
||||
const vNodeRef = useRef(null) as unknown as { current: VNode };
|
||||
vNodeRef.current = processingVNode;
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -239,7 +237,7 @@ function hookStore() {
|
|||
} else if (processingVNode.tag === ClassComponent) {
|
||||
// from ClassComponent
|
||||
if (!processingVNode.classComponentWillUnmount) {
|
||||
processingVNode.classComponentWillUnmount = function(vNode) {
|
||||
processingVNode.classComponentWillUnmount = function (vNode) {
|
||||
clearVNodeObservers(vNode);
|
||||
vNode.observers = null;
|
||||
};
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
import type { VNode } from '../Types';
|
||||
|
||||
import {
|
||||
ContextProvider,
|
||||
DomComponent,
|
||||
DomPortal,
|
||||
TreeRoot,
|
||||
SuspenseComponent,
|
||||
} from '../vnode/VNodeTags';
|
||||
import { ContextProvider, DomComponent, DomPortal, TreeRoot, SuspenseComponent } from '../vnode/VNodeTags';
|
||||
import { setContext, setNamespaceCtx } from '../ContextSaver';
|
||||
import { FlagUtils } from '../vnode/VNodeFlags';
|
||||
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
||||
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
|
||||
import componentRenders from './index';
|
||||
import {setProcessingVNode} from '../GlobalVar';
|
||||
import { setProcessingVNode } from '../GlobalVar';
|
||||
import { clearVNodeObservers } from '../../horizonx/store/StoreHandler';
|
||||
|
||||
// 复用vNode时,也需对stack进行处理
|
||||
|
@ -40,11 +34,7 @@ export function captureVNode(processing: VNode): VNode | null {
|
|||
|
||||
if (processing.tag !== SuspenseComponent) {
|
||||
// 该vNode没有变化,不用进入capture,直接复用。
|
||||
if (
|
||||
!processing.isCreated &&
|
||||
processing.oldProps === processing.props &&
|
||||
!processing.shouldUpdate
|
||||
) {
|
||||
if (!processing.isCreated && processing.oldProps === processing.props && !processing.shouldUpdate) {
|
||||
// 复用还需对stack进行处理
|
||||
handlerContext(processing);
|
||||
|
||||
|
@ -56,8 +46,8 @@ export function captureVNode(processing: VNode): VNode | null {
|
|||
processing.shouldUpdate = false;
|
||||
|
||||
setProcessingVNode(processing);
|
||||
|
||||
if(processing.observers) clearVNodeObservers(processing);
|
||||
|
||||
if (processing.observers) clearVNodeObservers(processing);
|
||||
const child = component.captureRender(processing, shouldUpdate);
|
||||
setProcessingVNode(null);
|
||||
|
||||
|
|
|
@ -1,132 +1,130 @@
|
|||
import { createStore } from "@cloudsop/horizon/src/horizonx/store/StoreHandler";
|
||||
import { watch } from "@cloudsop/horizon/src/horizonx/proxy/watch";
|
||||
import { createStore } from '@cloudsop/horizon/src/horizonx/store/StoreHandler';
|
||||
import { watch } from '@cloudsop/horizon/src/horizonx/proxy/watch';
|
||||
|
||||
describe("watch",()=>{
|
||||
it('shouhld watch promitive state variable', async()=>{
|
||||
const useStore = createStore({
|
||||
state:{
|
||||
variable:'x'
|
||||
},
|
||||
actions:{
|
||||
change:(state)=>state.variable = "a"
|
||||
}
|
||||
});
|
||||
|
||||
const store = useStore();
|
||||
let counter = 0;
|
||||
|
||||
watch(store.$s,(state)=>{
|
||||
counter++;
|
||||
expect(state.variable).toBe('a');
|
||||
})
|
||||
|
||||
store.change();
|
||||
|
||||
expect(counter).toBe(1);
|
||||
});
|
||||
it('shouhld watch object variable', async()=>{
|
||||
const useStore = createStore({
|
||||
state:{
|
||||
variable:'x'
|
||||
},
|
||||
actions:{
|
||||
change:(state)=>state.variable = "a"
|
||||
}
|
||||
});
|
||||
|
||||
const store = useStore();
|
||||
let counter = 0;
|
||||
|
||||
store.$s.watch('variable',()=>{
|
||||
counter++;
|
||||
})
|
||||
|
||||
store.change();
|
||||
|
||||
expect(counter).toBe(1);
|
||||
describe('watch', () => {
|
||||
it('shouhld watch promitive state variable', async () => {
|
||||
const useStore = createStore({
|
||||
state: {
|
||||
variable: 'x',
|
||||
},
|
||||
actions: {
|
||||
change: state => (state.variable = 'a'),
|
||||
},
|
||||
});
|
||||
|
||||
it('shouhld watch array item', async()=>{
|
||||
const useStore = createStore({
|
||||
state:{
|
||||
arr:['x']
|
||||
},
|
||||
actions:{
|
||||
change:(state)=>state.arr[0]='a'
|
||||
}
|
||||
});
|
||||
const store = useStore();
|
||||
let counter = 0;
|
||||
|
||||
const store = useStore();
|
||||
let counter = 0;
|
||||
|
||||
store.arr.watch('0',()=>{
|
||||
counter++;
|
||||
})
|
||||
|
||||
store.change();
|
||||
|
||||
expect(counter).toBe(1);
|
||||
watch(store.$s, state => {
|
||||
counter++;
|
||||
expect(state.variable).toBe('a');
|
||||
});
|
||||
|
||||
it('shouhld watch collection item', async()=>{
|
||||
const useStore = createStore({
|
||||
state:{
|
||||
collection:new Map([
|
||||
['a', 'a'],
|
||||
])
|
||||
},
|
||||
actions:{
|
||||
change:(state)=>state.collection.set('a','x')
|
||||
}
|
||||
});
|
||||
store.change();
|
||||
|
||||
const store = useStore();
|
||||
let counter = 0;
|
||||
|
||||
store.collection.watch('a',()=>{
|
||||
counter++;
|
||||
})
|
||||
|
||||
store.change();
|
||||
|
||||
expect(counter).toBe(1);
|
||||
expect(counter).toBe(1);
|
||||
});
|
||||
it('shouhld watch object variable', async () => {
|
||||
const useStore = createStore({
|
||||
state: {
|
||||
variable: 'x',
|
||||
},
|
||||
actions: {
|
||||
change: state => (state.variable = 'a'),
|
||||
},
|
||||
});
|
||||
|
||||
it('should watch multiple variables independedntly', async()=>{
|
||||
const useStore = createStore({
|
||||
state:{
|
||||
bool1:true,
|
||||
bool2:false
|
||||
},
|
||||
actions:{
|
||||
toggle1:state=>state.bool1=!state.bool1,
|
||||
toggle2:state=>state.bool2=!state.bool2
|
||||
}
|
||||
});
|
||||
const store = useStore();
|
||||
let counter = 0;
|
||||
|
||||
let counter1=0;
|
||||
let counterAll=0;
|
||||
const store = useStore();
|
||||
store.$s.watch('variable', () => {
|
||||
counter++;
|
||||
});
|
||||
|
||||
watch(store.$s,()=>{
|
||||
counterAll++;
|
||||
})
|
||||
store.change();
|
||||
|
||||
store.$s.watch('bool1',()=>{
|
||||
counter1++;
|
||||
});
|
||||
expect(counter).toBe(1);
|
||||
});
|
||||
|
||||
store.toggle1();
|
||||
store.toggle1();
|
||||
it('shouhld watch array item', async () => {
|
||||
const useStore = createStore({
|
||||
state: {
|
||||
arr: ['x'],
|
||||
},
|
||||
actions: {
|
||||
change: state => (state.arr[0] = 'a'),
|
||||
},
|
||||
});
|
||||
|
||||
store.toggle2();
|
||||
const store = useStore();
|
||||
let counter = 0;
|
||||
|
||||
store.toggle1();
|
||||
store.arr.watch('0', () => {
|
||||
counter++;
|
||||
});
|
||||
|
||||
store.toggle2();
|
||||
store.toggle2();
|
||||
store.change();
|
||||
|
||||
expect(counter1).toBe(3);
|
||||
expect(counterAll).toBe(6);
|
||||
})
|
||||
})
|
||||
expect(counter).toBe(1);
|
||||
});
|
||||
|
||||
it('shouhld watch collection item', async () => {
|
||||
const useStore = createStore({
|
||||
state: {
|
||||
collection: new Map([['a', 'a']]),
|
||||
},
|
||||
actions: {
|
||||
change: state => state.collection.set('a', 'x'),
|
||||
},
|
||||
});
|
||||
|
||||
const store = useStore();
|
||||
let counter = 0;
|
||||
|
||||
store.collection.watch('a', () => {
|
||||
counter++;
|
||||
});
|
||||
|
||||
store.change();
|
||||
|
||||
expect(counter).toBe(1);
|
||||
});
|
||||
|
||||
it('should watch multiple variables independedntly', async () => {
|
||||
const useStore = createStore({
|
||||
state: {
|
||||
bool1: true,
|
||||
bool2: false,
|
||||
},
|
||||
actions: {
|
||||
toggle1: state => (state.bool1 = !state.bool1),
|
||||
toggle2: state => (state.bool2 = !state.bool2),
|
||||
},
|
||||
});
|
||||
|
||||
let counter1 = 0;
|
||||
let counterAll = 0;
|
||||
const store = useStore();
|
||||
|
||||
watch(store.$s, () => {
|
||||
counterAll++;
|
||||
});
|
||||
|
||||
store.$s.watch('bool1', () => {
|
||||
counter1++;
|
||||
});
|
||||
|
||||
store.toggle1();
|
||||
store.toggle1();
|
||||
|
||||
store.toggle2();
|
||||
|
||||
store.toggle1();
|
||||
|
||||
store.toggle2();
|
||||
store.toggle2();
|
||||
|
||||
expect(counter1).toBe(3);
|
||||
expect(counterAll).toBe(6);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,20 +6,20 @@ import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
|
|||
const { unmountComponentAtNode } = Horizon;
|
||||
|
||||
const useStore1 = createStore({
|
||||
state:{ counter:1 },
|
||||
actions:{
|
||||
add:(state)=>state.counter++,
|
||||
reset: (state)=>state.counter=1
|
||||
}
|
||||
})
|
||||
state: { counter: 1 },
|
||||
actions: {
|
||||
add: state => state.counter++,
|
||||
reset: state => (state.counter = 1),
|
||||
},
|
||||
});
|
||||
|
||||
const useStore2 = createStore({
|
||||
state:{ counter2:1 },
|
||||
actions:{
|
||||
add2:(state)=>state.counter2++,
|
||||
reset: (state)=>state.counter2=1
|
||||
}
|
||||
})
|
||||
state: { counter2: 1 },
|
||||
actions: {
|
||||
add2: state => state.counter2++,
|
||||
reset: state => (state.counter2 = 1),
|
||||
},
|
||||
});
|
||||
|
||||
describe('Using multiple stores', () => {
|
||||
let container: HTMLElement | null = null;
|
||||
|
@ -42,10 +42,10 @@ describe('Using multiple stores', () => {
|
|||
});
|
||||
|
||||
it('Should use multiple stores in class component', () => {
|
||||
class App extends Horizon.Component{
|
||||
render(){
|
||||
const {counter,add} = useStore1();
|
||||
const {counter2, add2} = useStore2();
|
||||
class App extends Horizon.Component {
|
||||
render() {
|
||||
const { counter, add } = useStore1();
|
||||
const { counter2, add2 } = useStore2();
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -65,9 +65,11 @@ describe('Using multiple stores', () => {
|
|||
>
|
||||
add
|
||||
</button>
|
||||
<p id={RESULT_ID}>{counter} {counter2}</p>
|
||||
<p id={RESULT_ID}>
|
||||
{counter} {counter2}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,39 +78,36 @@ describe('Using multiple stores', () => {
|
|||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('1 1');
|
||||
Horizon.act(() => {
|
||||
triggerClickEvent(container, BUTTON_ID);
|
||||
|
||||
});
|
||||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('2 1');
|
||||
|
||||
Horizon.act(() => {
|
||||
triggerClickEvent(container, BUTTON_ID2);
|
||||
|
||||
});
|
||||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('2 2');
|
||||
|
||||
});
|
||||
|
||||
it('Should use use stores in cycles and multiple methods', () => {
|
||||
interface App {
|
||||
store:any,
|
||||
store2:any
|
||||
store: any;
|
||||
store2: any;
|
||||
}
|
||||
class App extends Horizon.Component{
|
||||
constructor(){
|
||||
class App extends Horizon.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.store = useStore1();
|
||||
this.store2 = useStore2()
|
||||
this.store2 = useStore2();
|
||||
}
|
||||
|
||||
render(){
|
||||
const {counter,add} = useStore1();
|
||||
render() {
|
||||
const { counter, add } = useStore1();
|
||||
const store2 = useStore2();
|
||||
const {counter2, add2} = store2;
|
||||
const { counter2, add2 } = store2;
|
||||
|
||||
for(let i=0; i<100; i++){
|
||||
const {counter,add} = useStore1();
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const { counter, add } = useStore1();
|
||||
const store2 = useStore2();
|
||||
const {counter2, add2} = store2;
|
||||
const { counter2, add2 } = store2;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -129,34 +128,33 @@ describe('Using multiple stores', () => {
|
|||
>
|
||||
add
|
||||
</button>
|
||||
<p id={RESULT_ID}>{counter} {counter2}</p>
|
||||
<p id={RESULT_ID}>
|
||||
{counter} {counter2}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Horizon.render(<App />, container);
|
||||
|
||||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('1 1');
|
||||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('1 1');
|
||||
Horizon.act(() => {
|
||||
triggerClickEvent(container, BUTTON_ID);
|
||||
|
||||
});
|
||||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('2 1');
|
||||
|
||||
Horizon.act(() => {
|
||||
triggerClickEvent(container, BUTTON_ID2);
|
||||
|
||||
});
|
||||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('2 2');
|
||||
|
||||
});
|
||||
|
||||
it('Should use multiple stores in function component', () => {
|
||||
function App() {
|
||||
const {counter,add} = useStore1();
|
||||
const { counter, add } = useStore1();
|
||||
const store2 = useStore2();
|
||||
const {counter2, add2} = store2;
|
||||
const { counter2, add2 } = store2;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -176,7 +174,9 @@ describe('Using multiple stores', () => {
|
|||
>
|
||||
add
|
||||
</button>
|
||||
<p id={RESULT_ID}>{counter} {counter2}</p>
|
||||
<p id={RESULT_ID}>
|
||||
{counter} {counter2}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -186,14 +186,12 @@ describe('Using multiple stores', () => {
|
|||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('1 1');
|
||||
Horizon.act(() => {
|
||||
triggerClickEvent(container, BUTTON_ID);
|
||||
|
||||
});
|
||||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('2 1');
|
||||
|
||||
Horizon.act(() => {
|
||||
triggerClickEvent(container, BUTTON_ID2);
|
||||
|
||||
});
|
||||
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('2 2');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue