diff --git a/lib/src/components/ComponentWrapper.tsx b/lib/src/components/ComponentWrapper.tsx index f561dcf8d0a..6a7c86a3c5f 100644 --- a/lib/src/components/ComponentWrapper.tsx +++ b/lib/src/components/ComponentWrapper.tsx @@ -6,8 +6,13 @@ import hoistNonReactStatics from 'hoist-non-react-statics'; import { Store } from './Store'; import { ComponentEventsObserver } from '../events/ComponentEventsObserver'; -interface HocState { componentId: string; allProps: {}; } -interface HocProps { componentId: string; } +interface HocState { + componentId: string; + allProps: {}; +} +interface HocProps { + componentId: string; +} export interface IWrappedComponent extends React.Component { setProps(newProps: Record): void; @@ -29,8 +34,8 @@ export class ComponentWrapper { return { allProps: { ...nextProps, - ...store.getPropsForId(prevState.componentId) - } + ...store.getPropsForId(prevState.componentId), + }, }; } @@ -39,13 +44,18 @@ export class ComponentWrapper { this._assertComponentId(); this.state = { componentId: props.componentId, - allProps: {} + allProps: {}, }; store.setComponentInstance(props.componentId, this); } public setProps(newProps: any) { - this.setState({ allProps: newProps }); + this.setState((prevState) => ({ + allProps: { + ...prevState.allProps, + ...newProps, + }, + })); } componentWillUnmount() { @@ -55,10 +65,7 @@ export class ComponentWrapper { render() { return ( - + ); } @@ -70,11 +77,22 @@ export class ComponentWrapper { } polyfill(WrappedComponent); - hoistNonReactStatics(WrappedComponent, concreteComponentProvider === OriginalComponentGenerator ? GeneratedComponentClass : concreteComponentProvider()); - return ReduxProvider ? this.wrapWithRedux(WrappedComponent, ReduxProvider, reduxStore) : WrappedComponent; + hoistNonReactStatics( + WrappedComponent, + concreteComponentProvider === OriginalComponentGenerator + ? GeneratedComponentClass + : concreteComponentProvider() + ); + return ReduxProvider + ? this.wrapWithRedux(WrappedComponent, ReduxProvider, reduxStore) + : WrappedComponent; } - wrapWithRedux(WrappedComponent: React.ComponentClass, ReduxProvider: any, reduxStore: any): React.ComponentClass { + wrapWithRedux( + WrappedComponent: React.ComponentClass, + ReduxProvider: any, + reduxStore: any + ): React.ComponentClass { class ReduxWrapper extends React.Component { render() { return ( diff --git a/lib/src/components/Store.test.ts b/lib/src/components/Store.test.ts index 3009dda7b3a..a24117b360d 100644 --- a/lib/src/components/Store.test.ts +++ b/lib/src/components/Store.test.ts @@ -36,18 +36,18 @@ describe('Store', () => { }); it('clear instance by component id when clear component', () => { - uut.setComponentInstance('refUniqueId', ({} as IWrappedComponent)); + uut.setComponentInstance('refUniqueId', {} as IWrappedComponent); uut.clearComponent('refUniqueId'); expect(uut.getComponentInstance('refUniqueId')).toEqual(undefined); }); it('holds component instance by id', () => { - uut.setComponentInstance('component1', ({} as IWrappedComponent)); + uut.setComponentInstance('component1', {} as IWrappedComponent); expect(uut.getComponentInstance('component1')).toEqual({}); }); it('calls component setProps when set props by id', () => { - const instance: any = {setProps: jest.fn()}; + const instance: any = { setProps: jest.fn() }; const props = { foo: 'bar' }; uut.setComponentInstance('component1', instance); @@ -76,4 +76,11 @@ describe('Store', () => { expect(uut.getComponentClassForName('lazy')).toEqual(MyLazyComponent); expect(lazyRegistrator).toHaveBeenCalledTimes(1); }); + + it('keeps the old props when updateProps is called', () => { + uut.updateProps('component1', { foo: 'foo', bar: 'bar' }); + uut.updateProps('component1', { foo: 'foo2' }); + + expect(uut.getPropsForId('component1')).toEqual({ foo: 'foo2', bar: 'bar' }); + }); }); diff --git a/lib/src/components/Store.ts b/lib/src/components/Store.ts index 8d1ff309c5d..cd1368291f2 100644 --- a/lib/src/components/Store.ts +++ b/lib/src/components/Store.ts @@ -10,7 +10,7 @@ export class Store { private lazyRegistratorFn: ((lazyComponentRequest: string | number) => void) | undefined; updateProps(componentId: string, props: any) { - this.propsById[componentId] = props; + this.mergeNewPropsForId(componentId, props); const component = this.componentsInstancesById[componentId]; if (component) { this.componentsInstancesById[componentId].setProps(props); @@ -21,6 +21,14 @@ export class Store { return this.propsById[componentId] || {}; } + mergeNewPropsForId(componentId: string, newProps: any) { + const currentProps = this.getPropsForId(componentId); + this.propsById[componentId] = { + ...currentProps, + ...newProps, + }; + } + clearComponent(componentId: string) { delete this.propsById[componentId]; delete this.componentsInstancesById[componentId];