Match-id-99816485a3994e661f2c58e75d8f852e44192ecc
This commit is contained in:
parent
2ca9803cd9
commit
2ba2d78d4f
|
@ -45,13 +45,28 @@ export function resetContext(providerVNode: VNode) {
|
||||||
context.value = providerVNode.context;
|
context.value = providerVNode.context;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在局部更新时,恢复父节点的context
|
// 在局部更新时,从上到下恢复父节点的context
|
||||||
export function recoverParentContext(vNode: VNode) {
|
export function recoverParentContext(vNode: VNode) {
|
||||||
|
const contextProviders: VNode[] = [];
|
||||||
|
let parent = vNode.parent;
|
||||||
|
while (parent !== null) {
|
||||||
|
if (parent.tag === ContextProvider) {
|
||||||
|
contextProviders.unshift(parent);
|
||||||
|
}
|
||||||
|
parent = parent.parent;
|
||||||
|
}
|
||||||
|
contextProviders.forEach(node => {
|
||||||
|
setContext(node, node.props.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在局部更新时,从下到上重置父节点的context
|
||||||
|
export function resetParentContext(vNode: VNode) {
|
||||||
let parent = vNode.parent;
|
let parent = vNode.parent;
|
||||||
|
|
||||||
while (parent !== null) {
|
while (parent !== null) {
|
||||||
if (parent.tag === ContextProvider) {
|
if (parent.tag === ContextProvider) {
|
||||||
setContext(parent, parent.props.value);
|
resetContext(parent);
|
||||||
}
|
}
|
||||||
parent = parent.parent;
|
parent = parent.parent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import {
|
||||||
isExecuting,
|
isExecuting,
|
||||||
setExecuteMode
|
setExecuteMode
|
||||||
} from './ExecuteMode';
|
} from './ExecuteMode';
|
||||||
import { recoverParentContext, resetNamespaceCtx, setNamespaceCtx } from './ContextSaver';
|
import { recoverParentContext, resetParentContext, resetNamespaceCtx, setNamespaceCtx } from './ContextSaver';
|
||||||
import {
|
import {
|
||||||
updateChildShouldUpdate,
|
updateChildShouldUpdate,
|
||||||
updateParentsChildShouldUpdate,
|
updateParentsChildShouldUpdate,
|
||||||
|
@ -263,6 +263,10 @@ function buildVNodeTree(treeRoot: VNode) {
|
||||||
handleError(treeRoot, thrownValue);
|
handleError(treeRoot, thrownValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (startVNode.tag !== TreeRoot) { // 不是根节点
|
||||||
|
// 恢复父节点的context
|
||||||
|
resetParentContext(startVNode);
|
||||||
|
}
|
||||||
|
|
||||||
setProcessingClassVNode(null);
|
setProcessingClassVNode(null);
|
||||||
|
|
||||||
|
|
|
@ -358,4 +358,79 @@ describe('Context Test', () => {
|
||||||
Horizon.render(<App num={8} type={'typeR'} />, container);
|
Horizon.render(<App num={8} type={'typeR'} />, container);
|
||||||
expect(container.querySelector('p').innerHTML).toBe('Num: 8, Type: typeR');
|
expect(container.querySelector('p').innerHTML).toBe('Num: 8, Type: typeR');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// antd menu 级连context场景,menu路径使用级联context实现
|
||||||
|
it('nested context', () => {
|
||||||
|
const NestedContext = Horizon.createContext([]);
|
||||||
|
let updateContext;
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const [state, useState] = Horizon.useState([]);
|
||||||
|
updateContext = useState;
|
||||||
|
return (
|
||||||
|
<NestedContext.Provider value={state}>
|
||||||
|
<Sub1 />
|
||||||
|
<Sub2 />
|
||||||
|
</NestedContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const div1Ref = Horizon.createRef();
|
||||||
|
const div2Ref = Horizon.createRef();
|
||||||
|
|
||||||
|
let updateSub1;
|
||||||
|
function Sub1() {
|
||||||
|
const path = Horizon.useContext(NestedContext);
|
||||||
|
const [_, setState] = Horizon.useState({});
|
||||||
|
updateSub1 = () => setState({});
|
||||||
|
return (
|
||||||
|
<NestedContext.Provider value={[...path, 1]}>
|
||||||
|
<Son divRef={div1Ref} />
|
||||||
|
</NestedContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Sub2() {
|
||||||
|
const path = Horizon.useContext(NestedContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NestedContext.Provider value={[...path, 2]}>
|
||||||
|
<Sub3 />
|
||||||
|
</NestedContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Sub3() {
|
||||||
|
const path = Horizon.useContext(NestedContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NestedContext.Provider value={[...path, 3]}>
|
||||||
|
<Son divRef={div2Ref} />
|
||||||
|
</NestedContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Son({ divRef }) {
|
||||||
|
const path = Horizon.useContext(NestedContext);
|
||||||
|
return (
|
||||||
|
<NestedContext.Provider value={path}>
|
||||||
|
<div ref={divRef}>{path.join(',')}</div>
|
||||||
|
</NestedContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Horizon.render(<App />, container);
|
||||||
|
updateSub1();
|
||||||
|
expect(div1Ref.current.innerHTML).toEqual('1');
|
||||||
|
expect(div2Ref.current.innerHTML).toEqual('2,3');
|
||||||
|
|
||||||
|
updateContext([0]);
|
||||||
|
expect(div1Ref.current.innerHTML).toEqual('0,1');
|
||||||
|
expect(div2Ref.current.innerHTML).toEqual('0,2,3');
|
||||||
|
|
||||||
|
// 局部更新Sub1
|
||||||
|
updateSub1();
|
||||||
|
expect(div1Ref.current.innerHTML).toEqual('0,1');
|
||||||
|
expect(div2Ref.current.innerHTML).toEqual('0,2,3');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue