Browse Source

merge static memebers from wrapped components #3322

Daniel Zlotin 6 years ago
parent
commit
c5948d1d75

+ 4
- 0
integration/remx/MyComponent.js View File

6
 const store = require('./MyStore');
6
 const store = require('./MyStore');
7
 
7
 
8
 class MyComponent extends Component {
8
 class MyComponent extends Component {
9
+  static options = {
10
+    title: 'MyComponent'
11
+  };
12
+
9
   render() {
13
   render() {
10
     if (this.props.renderCountIncrement) {
14
     if (this.props.renderCountIncrement) {
11
       this.props.renderCountIncrement();
15
       this.props.renderCountIncrement();

+ 8
- 0
integration/remx/remx.test.js View File

1
 const React = require('react');
1
 const React = require('react');
2
 require('react-native');
2
 require('react-native');
3
 const renderer = require('react-test-renderer');
3
 const renderer = require('react-test-renderer');
4
+const { Navigation } = require('../../lib/dist/index');
4
 
5
 
5
 describe('remx support', () => {
6
 describe('remx support', () => {
6
   let MyConnectedComponent;
7
   let MyConnectedComponent;
43
 
44
 
44
     expect(renderCountIncrement).toHaveBeenCalledTimes(2);
45
     expect(renderCountIncrement).toHaveBeenCalledTimes(2);
45
   });
46
   });
47
+
48
+  it('support for static members in connected components', () => {
49
+    expect(MyConnectedComponent.options).toEqual({ title: 'MyComponent' });
50
+
51
+    const registeredComponentClass = Navigation.componentRegistry.registerComponent('MyComponentName', () => MyConnectedComponent);
52
+    expect(registeredComponentClass.options).toEqual({ title: 'MyComponent' });
53
+  });
46
 });
54
 });

+ 3
- 2
lib/src/Navigation.ts View File

12
 import { ComponentEventsObserver } from './events/ComponentEventsObserver';
12
 import { ComponentEventsObserver } from './events/ComponentEventsObserver';
13
 import { CommandsObserver } from './events/CommandsObserver';
13
 import { CommandsObserver } from './events/CommandsObserver';
14
 import { Constants } from './adapters/Constants';
14
 import { Constants } from './adapters/Constants';
15
+import { ComponentType } from 'react';
15
 
16
 
16
 export class Navigation {
17
 export class Navigation {
17
   public readonly Element: React.ComponentType<{ elementId: any; resizeMode: any; }>;
18
   public readonly Element: React.ComponentType<{ elementId: any; resizeMode: any; }>;
48
    * Every navigation component in your app must be registered with a unique name.
49
    * Every navigation component in your app must be registered with a unique name.
49
    * The component itself is a traditional React component extending React.Component.
50
    * The component itself is a traditional React component extending React.Component.
50
    */
51
    */
51
-  public registerComponent(componentName: string, getComponentClassFunc: ComponentProvider): void {
52
-    this.componentRegistry.registerComponent(componentName, getComponentClassFunc);
52
+  public registerComponent(componentName: string, getComponentClassFunc: ComponentProvider): ComponentType<any> {
53
+    return this.componentRegistry.registerComponent(componentName, getComponentClassFunc);
53
   }
54
   }
54
 
55
 
55
   /**
56
   /**

+ 2
- 1
lib/src/components/ComponentRegistry.test.tsx View File

28
 
28
 
29
   it('registers component component by componentName into AppRegistry', () => {
29
   it('registers component component by componentName into AppRegistry', () => {
30
     expect(mockRegistry).not.toHaveBeenCalled();
30
     expect(mockRegistry).not.toHaveBeenCalled();
31
-    uut.registerComponent('example.MyComponent.name', () => MyComponent);
31
+    const result = uut.registerComponent('example.MyComponent.name', () => MyComponent);
32
     expect(mockRegistry).toHaveBeenCalledTimes(1);
32
     expect(mockRegistry).toHaveBeenCalledTimes(1);
33
     expect(mockRegistry.mock.calls[0][0]).toEqual('example.MyComponent.name');
33
     expect(mockRegistry.mock.calls[0][0]).toEqual('example.MyComponent.name');
34
+    expect(mockRegistry.mock.calls[0][1]()).toEqual(result);
34
   });
35
   });
35
 
36
 
36
   it('saves the original component into the store', () => {
37
   it('saves the original component into the store', () => {

+ 3
- 1
lib/src/components/ComponentRegistry.ts View File

1
 import { AppRegistry, ComponentProvider } from 'react-native';
1
 import { AppRegistry, ComponentProvider } from 'react-native';
2
 import { ComponentWrapper } from './ComponentWrapper';
2
 import { ComponentWrapper } from './ComponentWrapper';
3
+import { ComponentType } from 'react';
3
 
4
 
4
 export class ComponentRegistry {
5
 export class ComponentRegistry {
5
   private store;
6
   private store;
8
     this.store = store;
9
     this.store = store;
9
   }
10
   }
10
 
11
 
11
-  registerComponent(componentName: string, getComponentClassFunc: ComponentProvider): void {
12
+  registerComponent(componentName: string, getComponentClassFunc: ComponentProvider): ComponentType<any> {
12
     const OriginalComponentClass = getComponentClassFunc();
13
     const OriginalComponentClass = getComponentClassFunc();
13
     const NavigationComponent = ComponentWrapper.wrap(componentName, OriginalComponentClass, this.store);
14
     const NavigationComponent = ComponentWrapper.wrap(componentName, OriginalComponentClass, this.store);
14
     this.store.setOriginalComponentClassForName(componentName, OriginalComponentClass);
15
     this.store.setOriginalComponentClassForName(componentName, OriginalComponentClass);
15
     AppRegistry.registerComponent(componentName, () => NavigationComponent);
16
     AppRegistry.registerComponent(componentName, () => NavigationComponent);
17
+    return NavigationComponent;
16
   }
18
   }
17
 }
19
 }

+ 9
- 0
lib/src/components/ComponentWrapper.test.tsx View File

16
   let childRef;
16
   let childRef;
17
 
17
 
18
   class MyComponent extends React.Component {
18
   class MyComponent extends React.Component {
19
+    static options = {
20
+      title: 'MyComponentTitle'
21
+    };
22
+
19
     render() {
23
     render() {
20
       return <Text>{'Hello, World!'}</Text>;
24
       return <Text>{'Hello, World!'}</Text>;
21
     }
25
     }
142
     expect(instance.originalComponentRef).toBeFalsy();
146
     expect(instance.originalComponentRef).toBeFalsy();
143
   });
147
   });
144
 
148
 
149
+  it(`merges static members from wrapped component`, () => {
150
+    const NavigationComponent = ComponentWrapper.wrap(componentName, MyComponent, store) as any;
151
+    expect(NavigationComponent.options).toEqual({ title: 'MyComponentTitle' });
152
+  });
153
+
145
   describe('component lifecycle', () => {
154
   describe('component lifecycle', () => {
146
     const componentDidAppearCallback = jest.fn();
155
     const componentDidAppearCallback = jest.fn();
147
     const componentDidDisappearCallback = jest.fn();
156
     const componentDidDisappearCallback = jest.fn();

+ 2
- 0
lib/src/components/ComponentWrapper.tsx View File

82
 
82
 
83
     ReactLifecyclesCompat.polyfill(WrappedComponent);
83
     ReactLifecyclesCompat.polyfill(WrappedComponent);
84
 
84
 
85
+    _.defaults(WrappedComponent, OriginalComponentClass);
86
+
85
     return WrappedComponent;
87
     return WrappedComponent;
86
   }
88
   }
87
 }
89
 }

+ 0
- 1
package.json View File

147
     }
147
     }
148
   }
148
   }
149
 }
149
 }
150
-