From 8d387af36248a64d5cc0dbc9c53aeef6580b77bb Mon Sep 17 00:00:00 2001 From: svbutko Date: Thu, 30 Sep 2021 10:03:31 +0300 Subject: [PATCH 1/3] Add callback as optional parameter to updateProps --- lib/src/Navigation.ts | 4 ++-- lib/src/commands/Commands.test.ts | 13 +++++++++++++ lib/src/commands/Commands.ts | 4 ++-- lib/src/components/ComponentWrapper.tsx | 6 +++--- lib/src/components/Store.ts | 4 ++-- website/docs/api/api-component.mdx | 9 +++++---- 6 files changed, 27 insertions(+), 13 deletions(-) diff --git a/lib/src/Navigation.ts b/lib/src/Navigation.ts index 9c80cc7b478..f14c176ef54 100644 --- a/lib/src/Navigation.ts +++ b/lib/src/Navigation.ts @@ -188,8 +188,8 @@ export class NavigationRoot { /** * Update a mounted component's props */ - public updateProps(componentId: string, props: object) { - this.commands.updateProps(componentId, props); + public updateProps(componentId: string, props: object, callback?: () => void) { + this.commands.updateProps(componentId, props, callback); } /** diff --git a/lib/src/commands/Commands.test.ts b/lib/src/commands/Commands.test.ts index 1e1ee4f10b7..c0465eb0774 100644 --- a/lib/src/commands/Commands.test.ts +++ b/lib/src/commands/Commands.test.ts @@ -242,6 +242,19 @@ describe('Commands', () => { ) ); }); + + test('update props with callback', done => { + function callback () { + try { + expect(true).toBe(true); + done(); + } catch (error) { + done(error); + } + } + + uut.updateProps('theComponentId', { someProp: 'someValue' }, callback); + }); }); describe('showModal', () => { diff --git a/lib/src/commands/Commands.ts b/lib/src/commands/Commands.ts index c2c3b6f566a..3defb11c912 100644 --- a/lib/src/commands/Commands.ts +++ b/lib/src/commands/Commands.ts @@ -85,8 +85,8 @@ export class Commands { this.commandsObserver.notify(CommandName.MergeOptions, { componentId, options }); } - public updateProps(componentId: string, props: object) { - this.store.updateProps(componentId, props); + public updateProps(componentId: string, props: object, callback?: () => void) { + this.store.updateProps(componentId, props, callback); this.commandsObserver.notify(CommandName.UpdateProps, { componentId, props }); } diff --git a/lib/src/components/ComponentWrapper.tsx b/lib/src/components/ComponentWrapper.tsx index ba4f6859040..f6444a33dfd 100644 --- a/lib/src/components/ComponentWrapper.tsx +++ b/lib/src/components/ComponentWrapper.tsx @@ -15,7 +15,7 @@ interface HocProps { } export interface IWrappedComponent extends React.Component { - setProps(newProps: Record): void; + setProps(newProps: Record, callback?: () => void): void; isMounted: boolean; } @@ -56,13 +56,13 @@ export class ComponentWrapper { store.setComponentInstance(props.componentId, this); } - public setProps(newProps: any) { + public setProps(newProps: any, callback?: () => void) { this.setState((prevState) => ({ allProps: { ...prevState.allProps, ...newProps, }, - })); + }), callback); } componentDidMount() { diff --git a/lib/src/components/Store.ts b/lib/src/components/Store.ts index 8038bc8deeb..6438768fd09 100644 --- a/lib/src/components/Store.ts +++ b/lib/src/components/Store.ts @@ -9,11 +9,11 @@ export class Store { private wrappedComponents: Record> = {}; private lazyRegistratorFn: ((lazyComponentRequest: string | number) => void) | undefined; - updateProps(componentId: string, props: any) { + updateProps(componentId: string, props: any, callback?: () => void) { this.mergeNewPropsForId(componentId, props); const component = this.componentsInstancesById[componentId]; if (component) { - this.componentsInstancesById[componentId].setProps(props); + this.componentsInstancesById[componentId].setProps(props, callback); } } diff --git a/website/docs/api/api-component.mdx b/website/docs/api/api-component.mdx index 53b00874ede..4d4387a57dc 100644 --- a/website/docs/api/api-component.mdx +++ b/website/docs/api/api-component.mdx @@ -57,10 +57,11 @@ Navigation.setLazyComponentRegistrator((componentName) => { Update props of a component registered with [registerComponent](#registercomponent). Updating props triggers the component lifecycle methods related to [updating](https://reactjs.org/docs/react-component.html#updating). #### Parameters -| Name | Required | Type | Description | -| ------ | -------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------- | -| componentId | Yes | string | Unique component id | -| options | Yes | object | props object to pass to the component | +| Name | Required | Type | Description | +| ----------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------- | +| componentId | Yes | string | Unique component id | +| options | Yes | object | Props object to pass to the component | +| callback | No | Function | Function that will be executed once inner `setState` is completed | #### Example ```js From c42fc08c45d70e7dfbcf3491d639c306eb95210e Mon Sep 17 00:00:00 2001 From: svbutko Date: Thu, 30 Sep 2021 10:14:05 +0300 Subject: [PATCH 2/3] Add optional callback to NavigationDelegate --- lib/src/NavigationDelegate.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/NavigationDelegate.ts b/lib/src/NavigationDelegate.ts index 90aecf18a88..2c27a0f62b9 100644 --- a/lib/src/NavigationDelegate.ts +++ b/lib/src/NavigationDelegate.ts @@ -113,8 +113,8 @@ export class NavigationDelegate { /** * Update a mounted component's props */ - public updateProps(componentId: string, props: object) { - this.concreteNavigation.updateProps(componentId, props); + public updateProps(componentId: string, props: object, callback?: () => void) { + this.concreteNavigation.updateProps(componentId, props, callback); } /** From 2d41b1213ce3bad82559689d49d5268457bee907 Mon Sep 17 00:00:00 2001 From: svbutko Date: Thu, 30 Sep 2021 10:36:16 +0300 Subject: [PATCH 3/3] Add tests to Store and ComponentWrapper --- lib/src/components/ComponentWrapper.test.tsx | 13 +++++++++++++ lib/src/components/Store.test.ts | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/src/components/ComponentWrapper.test.tsx b/lib/src/components/ComponentWrapper.test.tsx index b70a5d43686..a5e1d709160 100644 --- a/lib/src/components/ComponentWrapper.test.tsx +++ b/lib/src/components/ComponentWrapper.test.tsx @@ -121,6 +121,19 @@ describe('ComponentWrapper', () => { }); }); + test('update props with callback', done => { + function callback () { + try { + expect(true).toBe(true); + done(); + } catch (error) { + done(error); + } + } + + store.updateProps('component123', { someProp: 'someValue' }, callback); + }); + it('updates props from store into inner component', () => { const NavigationComponent = uut.wrap( componentName, diff --git a/lib/src/components/Store.test.ts b/lib/src/components/Store.test.ts index a24117b360d..454c18c0d70 100644 --- a/lib/src/components/Store.test.ts +++ b/lib/src/components/Store.test.ts @@ -23,6 +23,19 @@ describe('Store', () => { expect(uut.getPropsForId('component1')).toEqual({}); }); + test('update props with callback', done => { + function callback () { + try { + expect(true).toBe(true); + done(); + } catch (error) { + done(error); + } + } + + uut.updateProps('component1', { someProp: 'someValue' }, callback); + }); + it('holds original components classes by componentName', () => { const MyWrappedComponent = () => class MyComponent extends React.Component {}; uut.setComponentClassForName('example.mycomponent', MyWrappedComponent);