Match-id-54a5a3d3fbc51aec4ea99d064f9b5e751eb4225b
This commit is contained in:
commit
c918ea0924
|
@ -45,13 +45,28 @@ export function resetContext(providerVNode: VNode) {
|
|||
context.value = providerVNode.context;
|
||||
}
|
||||
|
||||
// 在局部更新时,恢复父节点的context
|
||||
// 在局部更新时,从上到下恢复父节点的context
|
||||
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;
|
||||
|
||||
while (parent !== null) {
|
||||
if (parent.tag === ContextProvider) {
|
||||
setContext(parent, parent.props.value);
|
||||
resetContext(parent);
|
||||
}
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import {
|
|||
isExecuting,
|
||||
setExecuteMode
|
||||
} from './ExecuteMode';
|
||||
import { recoverParentContext, resetNamespaceCtx, setNamespaceCtx } from './ContextSaver';
|
||||
import { recoverParentContext, resetParentContext, resetNamespaceCtx, setNamespaceCtx } from './ContextSaver';
|
||||
import {
|
||||
updateChildShouldUpdate,
|
||||
updateParentsChildShouldUpdate,
|
||||
|
@ -263,6 +263,10 @@ function buildVNodeTree(treeRoot: VNode) {
|
|||
handleError(treeRoot, thrownValue);
|
||||
}
|
||||
}
|
||||
if (startVNode.tag !== TreeRoot) { // 不是根节点
|
||||
// 恢复父节点的context
|
||||
resetParentContext(startVNode);
|
||||
}
|
||||
|
||||
setProcessingClassVNode(null);
|
||||
|
||||
|
|
|
@ -358,4 +358,79 @@ describe('Context Test', () => {
|
|||
Horizon.render(<App num={8} type={'typeR'} />, container);
|
||||
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