Skip to content

Commit

Permalink
memo: update api doc for globalState (#437)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbkillerf6 authored Apr 15, 2020
1 parent 9a795e0 commit 5c2aa9f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 35 deletions.
31 changes: 25 additions & 6 deletions docs/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
removeGlobalUncaughtErrorHandler(handler);
```

## `initGloabalState(state)`
## `initGloabalState(state)`

- Parameters

Expand All @@ -195,20 +195,39 @@

- onGlobalStateChange: `(callback: OnGlobalStateChangeCallback, fireImmediately?: boolean) => void` - Listen the global status in the current application: when state changes will trigger callback; fireImmediately = true, will trigger callback immediately when use this method.

- setGlobalState: `(state: Record<string, any>) => boolean` - Set global state.
- setGlobalState: `(state: Record<string, any>) => boolean` - Set global state by first layer props, it can just modify first layer props what has defined.

- offGlobalStateChange: `() => boolean` - Remove Listener in this app.
- offGlobalStateChange: `() => boolean` - Remove Listener in this app, will default trigger when app unmount.

- Sample

Master:
```ts
import { initGloabalState, MicroAppStateActions } from 'qiankun';
const actions: MicroAppStateActions = initGloabalState(state);
actions.onGlobalStateChange((state, prev) => console.log(state, prev));
actions.onGlobalStateChange((state, prev) => {
// state: new state; prev old state
console.log(state, prev);
});
actions.setGlobalState(state);
actions.offGlobalStateChange();
// PS: Slave can get actions through props, example: props.onGlobalStateChange(...).
```

Slave:
```ts
// get actions from mount
export function mount(props) {
props.onGlobalStateChange((state, prev) => {
// state: new state; prev old state
console.log(state, prev);
});
props.setGlobalState(state);
// It will trigger when slave umount, not necessary to use in non special cases.
props.offGlobalStateChange();
// ...
}
30 changes: 25 additions & 5 deletions docs/zh/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,21 +193,41 @@

- onGlobalStateChange: `(callback: OnGlobalStateChangeCallback, fireImmediately?: boolean) => void`, 在当前应用监听全局状态,有变更触发 callbackfireImmediately = true 立即触发 callback

- setGlobalState: `(state: Record<string, any>) => boolean`设置全局状态
- setGlobalState: `(state: Record<string, any>) => boolean`按一级属性设置全局状态,子应用中只能修改已存在的一级属性

- offGlobalStateChange: `() => boolean`,移除当前应用的状态监听
- offGlobalStateChange: `() => boolean`,移除当前应用的状态监听,子应用 umount 时会默认调用

- 示例

主应用:
```ts
import { initGloabalState, MicroAppStateActions } from 'qiankun';
// 初始化 state
const actions: MicroAppStateActions = initGloabalState(state);
actions.onGlobalStateChange((state, prev) => console.log(state, prev));
actions.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
console.log(state, prev);
});
actions.setGlobalState(state);
actions.offGlobalStateChange();
// 备注:子应用可以使用 props 获取方法,如 props.onGlobalStateChange(...)
```

子应用:
```ts
// 从生命周期 mount 中获取通信方法,使用方式和 master 一致
export function mount(props) {
props.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
console.log(state, prev);
});
props.setGlobalState(state);
// 子应用 umount 时会默认调用,非特殊情况不需要使用
props.offGlobalStateChange();
// ...
}
```
39 changes: 19 additions & 20 deletions src/__tests__/globalState.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const master = initGlobalState({ user: 'qiankun' });

test('test master to master actions', () => {
const callback1 = (state: Record<string, any>, prevState: Record<string, any>) => {
expect(state).toEqual({ user: 'master' });
expect(state).toEqual({ ignore: 'matser', user: 'master' });
expect(prevState).toEqual({ user: 'qiankun' });
};
master.onGlobalStateChange(callback1);
Expand All @@ -19,47 +19,46 @@ test('test master to master actions', () => {
});

const callback2 = (state: Record<string, any>, prevState: Record<string, any>) => {
expect(state).toEqual({ user: 'master' });
expect(prevState).toEqual({ user: 'master' });
expect(state).toEqual({ ignore: 'matser', user: 'master' });
expect(prevState).toEqual({ ignore: 'matser', user: 'master' });
};
master.onGlobalStateChange(callback2, true);

// 注销监听保证下一个 case 测试
master.offGlobalStateChange();
});

// gloabal: { user: 'master' }
// gloabal: { ignore: 'matser', user: 'master' }

const slaveA = getMicroAppStateActions('slaveA');

test('test master to slave actions', () => {
const slaveCallback1 = (state: Record<string, any>, prevState: Record<string, any>) => {
expect(state).toEqual({ user: 'master2' });
expect(prevState).toEqual({ user: 'master' });
expect(state).toEqual({ ignore: 'matser', user: 'master2' });
expect(prevState).toEqual({ ignore: 'matser', user: 'master' });
};
slaveA.onGlobalStateChange(slaveCallback1);

master.setGlobalState({
ignore: 'matser2',
user: 'master2',
});

const slaveCallback2 = (state: Record<string, any>, prevState: Record<string, any>) => {
expect(state).toEqual({ user: 'master2' });
expect(prevState).toEqual({ user: 'master2' });
expect(state).toEqual({ ignore: 'matser', user: 'master2' });
expect(prevState).toEqual({ ignore: 'matser', user: 'master2' });
};
slaveA.onGlobalStateChange(slaveCallback2, true);

// 注销监听保证下一个 case 测试
slaveA.offGlobalStateChange();
});

// gloabal: { user: 'master2' }
// gloabal: { ignore: 'matser', user: 'master2' }

test('test slave to master actions', () => {
const callback1 = (state: Record<string, any>, prevState: Record<string, any>) => {
expect(state).toEqual({ user: 'slaveA' });
expect(prevState).toEqual({ user: 'master2' });
expect(state).toEqual({ ignore: 'slaveA', user: 'slaveA' });
expect(prevState).toEqual({ ignore: 'matser', user: 'master2' });
};
master.onGlobalStateChange(callback1);

Expand All @@ -69,33 +68,33 @@ test('test slave to master actions', () => {
});

const callback2 = (state: Record<string, any>, prevState: Record<string, any>) => {
expect(state).toEqual({ user: 'slaveA' });
expect(prevState).toEqual({ user: 'slaveA' });
expect(state).toEqual({ ignore: 'slaveA', user: 'slaveA' });
expect(prevState).toEqual({ ignore: 'slaveA', user: 'slaveA' });
};
master.onGlobalStateChange(callback2, true);

// 注销监听保证下一个 case 测试
master.offGlobalStateChange();
});

// gloabal: { user: 'slaveA' }
// gloabal: { ignore: 'slaveA', user: 'slaveA' }

const slaveB = getMicroAppStateActions('slaveB');
test('test slave to slave actions', () => {
const callback1 = (state: Record<string, any>, prevState: Record<string, any>) => {
expect(state).toEqual({ user: 'slaveB' });
expect(prevState).toEqual({ user: 'slaveA' });
expect(state).toEqual({ ignore: 'slaveA', user: 'slaveB' });
expect(prevState).toEqual({ ignore: 'slaveA', user: 'slaveA' });
};
slaveA.onGlobalStateChange(callback1);

slaveB.setGlobalState({
ignore: 'slaveB',
ignore2: 'slaveB',
user: 'slaveB',
});

const callback2 = (state: Record<string, any>, prevState: Record<string, any>) => {
expect(state).toEqual({ user: 'slaveB' });
expect(prevState).toEqual({ user: 'slaveB' });
expect(state).toEqual({ ignore: 'slaveA', user: 'slaveB' });
expect(prevState).toEqual({ ignore: 'slaveA', user: 'slaveB' });
};
slaveA.onGlobalStateChange(callback2, true);
});
10 changes: 6 additions & 4 deletions src/globalState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ export function initGlobalState(state: Record<string, any> = {}) {
if (state === gloabalState) {
console.warn('[qiankun] state has not changed!');
} else {
const prevGloabalState = cloneDeep(gloabalState);
gloabalState = cloneDeep(state);
emitGloabl(gloabalState, gloabalState);
emitGloabl(gloabalState, prevGloabalState);
}
return getMicroAppStateActions(`gloabal-${+new Date()}`);
return getMicroAppStateActions(`gloabal-${+new Date()}`, true);
}

export function getMicroAppStateActions(id: string): MicroAppStateActions {
export function getMicroAppStateActions(id: string, isMaster?: boolean): MicroAppStateActions {
return {
/**
* onStateChange 全局依赖监听
Expand Down Expand Up @@ -75,11 +76,12 @@ export function getMicroAppStateActions(id: string): MicroAppStateActions {
console.warn('[qiankun] state has not changed!');
return false;
}

const changeKeys: string[] = [];
const prevGloabalState = cloneDeep(gloabalState);
gloabalState = cloneDeep(
Object.keys(state).reduce((_gloabalState, changeKey) => {
if (changeKey in _gloabalState) {
if (isMaster || changeKey in _gloabalState) {
changeKeys.push(changeKey);
return Object.assign(_gloabalState, { [changeKey]: state[changeKey] });
}
Expand Down

1 comment on commit 5c2aa9f

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for website ready!

Built with commit 5c2aa9f

https://https://qiankun-ff03qwtqt.now.sh

Please sign in to comment.