Match-id-2c5aabb8936793c38d7908e5b5a9c1126c5799ed
This commit is contained in:
commit
42d3046281
|
@ -1,38 +1,34 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: ['@babel/preset-typescript', ['@babel/preset-env', { targets: { node: 'current' } }]],
|
||||||
'@babel/react',
|
|
||||||
'@babel/preset-typescript',
|
|
||||||
['@babel/preset-env', { targets: { node: 'current' } }]
|
|
||||||
],
|
|
||||||
plugins: [
|
plugins: [
|
||||||
['@babel/plugin-proposal-class-properties', { loose: true }],
|
'@babel/plugin-syntax-jsx',
|
||||||
[
|
[
|
||||||
'@babel/plugin-proposal-object-rest-spread',
|
'@babel/plugin-transform-react-jsx',
|
||||||
{ loose: true, useBuiltIns: true },
|
{
|
||||||
|
pragma: 'Horizon.createElement',
|
||||||
|
pragmaFrag: 'Horizon.Fragment',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
['@babel/plugin-transform-template-literals', { loose: true }],
|
['@babel/plugin-proposal-class-properties', { loose: true }],
|
||||||
|
['@babel/plugin-proposal-private-methods', { loose: true }],
|
||||||
|
['@babel/plugin-proposal-private-property-in-object', { loose: true }],
|
||||||
'@babel/plugin-transform-object-assign',
|
'@babel/plugin-transform-object-assign',
|
||||||
'@babel/plugin-transform-literals',
|
|
||||||
'@babel/plugin-transform-arrow-functions',
|
|
||||||
'@babel/plugin-transform-block-scoped-functions',
|
|
||||||
'@babel/plugin-transform-object-super',
|
'@babel/plugin-transform-object-super',
|
||||||
|
['@babel/plugin-proposal-object-rest-spread', { loose: true, useBuiltIns: true }],
|
||||||
|
['@babel/plugin-transform-template-literals', { loose: true }],
|
||||||
|
'@babel/plugin-transform-arrow-functions',
|
||||||
|
'@babel/plugin-transform-literals',
|
||||||
|
'@babel/plugin-transform-for-of',
|
||||||
|
'@babel/plugin-transform-block-scoped-functions',
|
||||||
|
'@babel/plugin-transform-classes',
|
||||||
'@babel/plugin-transform-shorthand-properties',
|
'@babel/plugin-transform-shorthand-properties',
|
||||||
'@babel/plugin-transform-computed-properties',
|
'@babel/plugin-transform-computed-properties',
|
||||||
'@babel/plugin-transform-for-of',
|
|
||||||
['@babel/plugin-transform-spread', { loose: true, useBuiltIns: true }],
|
|
||||||
'@babel/plugin-transform-parameters',
|
'@babel/plugin-transform-parameters',
|
||||||
['@babel/plugin-transform-destructuring', { loose: true, useBuiltIns: true }],
|
['@babel/plugin-transform-spread', { loose: true, useBuiltIns: true }],
|
||||||
['@babel/plugin-transform-block-scoping', { throwIfClosureRequired: false }],
|
['@babel/plugin-transform-block-scoping', { throwIfClosureRequired: false }],
|
||||||
'@babel/plugin-transform-classes',
|
['@babel/plugin-transform-destructuring', { loose: true, useBuiltIns: true }],
|
||||||
'@babel/plugin-transform-runtime',
|
'@babel/plugin-transform-runtime',
|
||||||
'@babel/plugin-proposal-nullish-coalescing-operator',
|
'@babel/plugin-proposal-nullish-coalescing-operator',
|
||||||
'@babel/plugin-proposal-optional-chaining',
|
'@babel/plugin-proposal-optional-chaining',
|
||||||
['@babel/plugin-proposal-private-methods', { 'loose': true }],
|
|
||||||
['@babel/plugin-proposal-private-property-in-object', { 'loose': true }],
|
|
||||||
'@babel/plugin-syntax-jsx',
|
|
||||||
['@babel/plugin-transform-react-jsx', {
|
|
||||||
pragma: 'Horizon.createElement',
|
|
||||||
pragmaFrag: 'Horizon.Fragment'
|
|
||||||
}],
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
import type { Hook, Reducer, Trigger, Update } from './HookType';
|
import type { Hook, Reducer, Trigger, Update } from './HookType';
|
||||||
import {
|
import { createHook, getCurrentHook, throwNotInFuncError } from './BaseHook';
|
||||||
createHook,
|
import { launchUpdateFromVNode } from '../TreeBuilder';
|
||||||
getCurrentHook,
|
|
||||||
throwNotInFuncError
|
|
||||||
} from './BaseHook';
|
|
||||||
import {
|
|
||||||
launchUpdateFromVNode
|
|
||||||
} from '../TreeBuilder';
|
|
||||||
import { isSame } from '../utils/compare';
|
import { isSame } from '../utils/compare';
|
||||||
import { setStateChange } from '../render/FunctionComponent';
|
import { setStateChange } from '../render/FunctionComponent';
|
||||||
import { getHookStage, HookStage } from './HookStage';
|
import { getHookStage, HookStage } from './HookStage';
|
||||||
import type { VNode } from '../Types';
|
import type { VNode } from '../Types';
|
||||||
import {getProcessingVNode} from '../GlobalVar';
|
import { getProcessingVNode } from '../GlobalVar';
|
||||||
|
|
||||||
export function useReducerImpl<S, P, A>(reducer: (S, A) =>
|
export function useReducerImpl<S, P, A>(
|
||||||
S, initArg: P, init?: (P) => S, isUseState?: boolean): [S, Trigger<A>] | void {
|
reducer: (S, A) => S,
|
||||||
|
initArg: P,
|
||||||
|
init?: (P) => S,
|
||||||
|
isUseState?: boolean
|
||||||
|
): [S, Trigger<A>] | void {
|
||||||
const stage = getHookStage();
|
const stage = getHookStage();
|
||||||
if (stage === null) {
|
if (stage === null) {
|
||||||
throwNotInFuncError();
|
throwNotInFuncError();
|
||||||
|
@ -53,16 +51,19 @@ function insertUpdate<S, A>(action: A, hook: Hook<S, A>): Update<S, A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// setState, setReducer触发函数
|
// setState, setReducer触发函数
|
||||||
export function TriggerAction<S, A, T>(vNode: VNode, hook: Hook<S, A>, action: A) {
|
export function TriggerAction<S, A>(vNode: VNode, hook: Hook<S, A>, isUseState: boolean, action: A): void {
|
||||||
const newUpdate = insertUpdate(action, hook);
|
const newUpdate = insertUpdate(action, hook);
|
||||||
|
|
||||||
// 判断是否需要刷新
|
// 判断是否需要刷新
|
||||||
if (!vNode.shouldUpdate) {
|
if (!vNode.shouldUpdate && isUseState) {
|
||||||
const reducerObj = hook.state as Reducer<S, A>;
|
const { stateValue, reducer } = hook.state as Reducer<S, A>;
|
||||||
const { stateValue, reducer } = reducerObj;
|
|
||||||
|
|
||||||
|
if (reducer === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 在进入render阶段前reducer没有变化,可以复用state值,提升性能
|
// 在进入render阶段前reducer没有变化,可以复用state值,提升性能
|
||||||
newUpdate.state = reducer(stateValue, action);
|
newUpdate.state = reducer(stateValue, action);
|
||||||
|
|
||||||
// 标记为已经计算过,不需要重新计算了
|
// 标记为已经计算过,不需要重新计算了
|
||||||
newUpdate.didCalculated = true;
|
newUpdate.didCalculated = true;
|
||||||
|
|
||||||
|
@ -87,16 +88,17 @@ export function useReducerForInit<S, A>(reducer, initArg, init, isUseState?: boo
|
||||||
}
|
}
|
||||||
|
|
||||||
const hook = createHook();
|
const hook = createHook();
|
||||||
|
const trigger = TriggerAction.bind(null, getProcessingVNode(), hook, isUseState);
|
||||||
// 为hook.state赋值{状态值, 触发函数, reducer, updates更新数组, 是否是useState}
|
// 为hook.state赋值{状态值, 触发函数, reducer, updates更新数组, 是否是useState}
|
||||||
hook.state = {
|
hook.state = {
|
||||||
stateValue: stateValue,
|
stateValue: stateValue,
|
||||||
trigger: TriggerAction.bind(null, getProcessingVNode(), hook),
|
trigger,
|
||||||
reducer,
|
reducer,
|
||||||
updates: null,
|
updates: null,
|
||||||
isUseState
|
isUseState,
|
||||||
} as Reducer<S, A>;
|
} as Reducer<S, A>;
|
||||||
|
|
||||||
return [hook.state.stateValue, hook.state.trigger];
|
return [hook.state.stateValue, trigger];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新hook.state
|
// 更新hook.state
|
||||||
|
@ -136,5 +138,3 @@ function calculateNewState<S, A>(currentHookUpdates: Array<Update<S, A>>, curren
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,12 @@
|
||||||
"@babel/plugin-transform-object-assign": "7.16.7",
|
"@babel/plugin-transform-object-assign": "7.16.7",
|
||||||
"@babel/plugin-transform-object-super": "7.16.7",
|
"@babel/plugin-transform-object-super": "7.16.7",
|
||||||
"@babel/plugin-transform-parameters": "7.16.7",
|
"@babel/plugin-transform-parameters": "7.16.7",
|
||||||
|
"@babel/plugin-transform-react-jsx": "7.16.7",
|
||||||
"@babel/plugin-transform-runtime": "7.16.7",
|
"@babel/plugin-transform-runtime": "7.16.7",
|
||||||
"@babel/plugin-transform-shorthand-properties": "7.16.7",
|
"@babel/plugin-transform-shorthand-properties": "7.16.7",
|
||||||
"@babel/plugin-transform-spread": "7.16.7",
|
"@babel/plugin-transform-spread": "7.16.7",
|
||||||
"@babel/plugin-transform-template-literals": "7.16.7",
|
"@babel/plugin-transform-template-literals": "7.16.7",
|
||||||
"@babel/preset-env": "7.16.7",
|
"@babel/preset-env": "7.16.7",
|
||||||
"@babel/preset-react": "7.16.7",
|
|
||||||
"@babel/preset-typescript": "7.16.7",
|
"@babel/preset-typescript": "7.16.7",
|
||||||
"@rollup/plugin-babel": "^5.3.1",
|
"@rollup/plugin-babel": "^5.3.1",
|
||||||
"@rollup/plugin-node-resolve": "^13.3.0",
|
"@rollup/plugin-node-resolve": "^13.3.0",
|
||||||
|
|
|
@ -13,25 +13,25 @@ describe('useReducer Hook Test', () => {
|
||||||
return {
|
return {
|
||||||
...intlCar,
|
...intlCar,
|
||||||
logo: 'ford',
|
logo: 'ford',
|
||||||
price: 76
|
price: 76,
|
||||||
};
|
};
|
||||||
case 'bmw':
|
case 'bmw':
|
||||||
return {
|
return {
|
||||||
...intlCar,
|
...intlCar,
|
||||||
logo: 'bmw',
|
logo: 'bmw',
|
||||||
price: 100
|
price: 100,
|
||||||
};
|
};
|
||||||
case 'benz':
|
case 'benz':
|
||||||
return {
|
return {
|
||||||
...intlCar,
|
...intlCar,
|
||||||
logo: 'benz',
|
logo: 'benz',
|
||||||
price: 80
|
price: 80,
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
...intlCar,
|
...intlCar,
|
||||||
logo: 'audi',
|
logo: 'audi',
|
||||||
price: 88
|
price: 88,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -56,4 +56,34 @@ describe('useReducer Hook Test', () => {
|
||||||
expect(container.querySelector('p').innerHTML).toBe('audi');
|
expect(container.querySelector('p').innerHTML).toBe('audi');
|
||||||
expect(container.querySelector('#senP').innerHTML).toBe('88');
|
expect(container.querySelector('#senP').innerHTML).toBe('88');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('dispatch只触发一次', () => {
|
||||||
|
let nextId = 1;
|
||||||
|
const reducer = () => {
|
||||||
|
return { data: nextId++ };
|
||||||
|
};
|
||||||
|
const btnRef = Horizon.createRef();
|
||||||
|
const Main = () => {
|
||||||
|
const [{ data }, dispatch] = useReducer(reducer, { data: 0 });
|
||||||
|
const dispatchLogging = () => {
|
||||||
|
console.log('dispatch is called once');
|
||||||
|
dispatch();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button ref={btnRef} onClick={() => dispatchLogging()}>
|
||||||
|
increment
|
||||||
|
</button>
|
||||||
|
<div>{data}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Horizon.render(<Main />, container);
|
||||||
|
Horizon.act(() => {
|
||||||
|
btnRef.current.click();
|
||||||
|
});
|
||||||
|
expect(nextId).toBe(2);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue