Match-id-cec2ce18d7d08f5b4f5642c57aaa799038a73223
This commit is contained in:
parent
5484fa748a
commit
5d8eebf144
|
@ -204,7 +204,8 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
|
||||||
return createStoreHook(handler);
|
return createStoreHook(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearVNodeObservers(vNode) {
|
export function clearVNodeObservers(vNode) {
|
||||||
|
if(!vNode.observers) return;
|
||||||
vNode.observers.forEach(observer => {
|
vNode.observers.forEach(observer => {
|
||||||
observer.clearByVNode(vNode);
|
observer.clearByVNode(vNode);
|
||||||
});
|
});
|
||||||
|
@ -220,10 +221,7 @@ function hookStore() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processingVNode.observers) {
|
if (!processingVNode.observers) {
|
||||||
// 清除上一次缓存的Observer依赖
|
|
||||||
clearVNodeObservers(processingVNode);
|
|
||||||
} else {
|
|
||||||
processingVNode.observers = new Set<Observer>();
|
processingVNode.observers = new Set<Observer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { FlagUtils } from '../vnode/VNodeFlags';
|
||||||
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
||||||
import componentRenders from './index';
|
import componentRenders from './index';
|
||||||
import {setProcessingVNode} from '../GlobalVar';
|
import {setProcessingVNode} from '../GlobalVar';
|
||||||
|
import { clearVNodeObservers } from '../../horizonx/store/StoreHandler';
|
||||||
|
|
||||||
// 复用vNode时,也需对stack进行处理
|
// 复用vNode时,也需对stack进行处理
|
||||||
function handlerContext(processing: VNode) {
|
function handlerContext(processing: VNode) {
|
||||||
|
@ -55,6 +56,8 @@ export function captureVNode(processing: VNode): VNode | null {
|
||||||
processing.shouldUpdate = false;
|
processing.shouldUpdate = false;
|
||||||
|
|
||||||
setProcessingVNode(processing);
|
setProcessingVNode(processing);
|
||||||
|
|
||||||
|
clearVNodeObservers(processing);
|
||||||
const child = component.captureRender(processing, shouldUpdate);
|
const child = component.captureRender(processing, shouldUpdate);
|
||||||
setProcessingVNode(null);
|
setProcessingVNode(null);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
//@ts-ignore
|
||||||
|
import Horizon, { createStore } from '@cloudsop/horizon/index.ts';
|
||||||
|
import { triggerClickEvent } from '../../jest/commonComponents';
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const useStore2 = createStore({
|
||||||
|
state:{ counter2:1 },
|
||||||
|
actions:{
|
||||||
|
add2:(state)=>state.counter2++,
|
||||||
|
reset: (state)=>state.counter2=1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Using multiple stores', () => {
|
||||||
|
let container: HTMLElement | null = null;
|
||||||
|
|
||||||
|
const BUTTON_ID = 'btn';
|
||||||
|
const BUTTON_ID2 = 'btn2';
|
||||||
|
const RESULT_ID = 'result';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = document.createElement('div');
|
||||||
|
document.body.appendChild(container);
|
||||||
|
useStore1().reset();
|
||||||
|
useStore2().reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
unmountComponentAtNode(container);
|
||||||
|
container?.remove();
|
||||||
|
container = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should use multiple stores in class component', () => {
|
||||||
|
class App extends Horizon.Component{
|
||||||
|
render(){
|
||||||
|
const {counter,add} = useStore1();
|
||||||
|
const store2 = useStore2();
|
||||||
|
const {counter2, add2} = store2;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
id={BUTTON_ID}
|
||||||
|
onClick={() => {
|
||||||
|
add();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
add
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
id={BUTTON_ID2}
|
||||||
|
onClick={() => {
|
||||||
|
add2();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
add
|
||||||
|
</button>
|
||||||
|
<p id={RESULT_ID}>{counter*counter2}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Horizon.render(<App />, container);
|
||||||
|
|
||||||
|
Horizon.act(() => {
|
||||||
|
triggerClickEvent(container, BUTTON_ID);
|
||||||
|
triggerClickEvent(container, BUTTON_ID);
|
||||||
|
triggerClickEvent(container, BUTTON_ID2);
|
||||||
|
triggerClickEvent(container, BUTTON_ID2);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('9');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should use use stores in cycles and multiple methods', () => {
|
||||||
|
interface App {
|
||||||
|
store:any,
|
||||||
|
store2:any
|
||||||
|
}
|
||||||
|
class App extends Horizon.Component{
|
||||||
|
constructor(){
|
||||||
|
super();
|
||||||
|
this.store = useStore1();
|
||||||
|
this.store2 = useStore2()
|
||||||
|
}
|
||||||
|
|
||||||
|
render(){
|
||||||
|
const {counter,add} = useStore1();
|
||||||
|
const store2 = useStore2();
|
||||||
|
const {counter2, add2} = store2;
|
||||||
|
|
||||||
|
for(let i=0; i<100; i++){
|
||||||
|
const {counter,add} = useStore1();
|
||||||
|
const store2 = useStore2();
|
||||||
|
const {counter2, add2} = store2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
id={BUTTON_ID}
|
||||||
|
onClick={() => {
|
||||||
|
add();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
add
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
id={BUTTON_ID2}
|
||||||
|
onClick={() => {
|
||||||
|
this.store2.add2();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
add
|
||||||
|
</button>
|
||||||
|
<p id={RESULT_ID}>{counter*counter2}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Horizon.render(<App />, container);
|
||||||
|
|
||||||
|
Horizon.act(() => {
|
||||||
|
triggerClickEvent(container, BUTTON_ID);
|
||||||
|
triggerClickEvent(container, BUTTON_ID);
|
||||||
|
triggerClickEvent(container, BUTTON_ID2);
|
||||||
|
triggerClickEvent(container, BUTTON_ID2);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('9');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should use multiple stores in function component', () => {
|
||||||
|
function App() {
|
||||||
|
const {counter,add} = useStore1();
|
||||||
|
const store2 = useStore2();
|
||||||
|
const {counter2, add2} = store2;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
id={BUTTON_ID}
|
||||||
|
onClick={() => {
|
||||||
|
add();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
add
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
id={BUTTON_ID2}
|
||||||
|
onClick={() => {
|
||||||
|
add2();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
add
|
||||||
|
</button>
|
||||||
|
<p id={RESULT_ID}>{counter*counter2}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Horizon.render(<App />, container);
|
||||||
|
|
||||||
|
Horizon.act(() => {
|
||||||
|
triggerClickEvent(container, BUTTON_ID);
|
||||||
|
triggerClickEvent(container, BUTTON_ID);
|
||||||
|
triggerClickEvent(container, BUTTON_ID2);
|
||||||
|
triggerClickEvent(container, BUTTON_ID2);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('9');
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue