react-native-navigation的迁移库

ComponentWrapper.tsx 2.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import * as React from 'react';
  2. import { ComponentProvider } from 'react-native';
  3. import * as _ from 'lodash';
  4. import { polyfill } from 'react-lifecycles-compat';
  5. import hoistNonReactStatics = require('hoist-non-react-statics');
  6. import { Store } from './Store';
  7. import { ComponentEventsObserver } from '../events/ComponentEventsObserver';
  8. interface HocState { componentId: string; allProps: {}; }
  9. interface HocProps { componentId: string; }
  10. export class ComponentWrapper {
  11. wrap(
  12. componentName: string | number,
  13. OriginalComponentGenerator: ComponentProvider,
  14. store: Store,
  15. componentEventsObserver: ComponentEventsObserver,
  16. concreteComponentProvider: ComponentProvider = OriginalComponentGenerator,
  17. ReduxProvider?: any,
  18. reduxStore?: any
  19. ): React.ComponentClass<any> {
  20. const GeneratedComponentClass = OriginalComponentGenerator();
  21. class WrappedComponent extends React.Component<HocProps, HocState> {
  22. static getDerivedStateFromProps(nextProps: any, prevState: HocState) {
  23. return {
  24. allProps: _.merge({}, nextProps, store.getPropsForId(prevState.componentId))
  25. };
  26. }
  27. constructor(props: HocProps) {
  28. super(props);
  29. this._assertComponentId();
  30. this.state = {
  31. componentId: props.componentId,
  32. allProps: {}
  33. };
  34. }
  35. componentWillUnmount() {
  36. store.cleanId(this.state.componentId);
  37. componentEventsObserver.unmounted(this.state.componentId);
  38. }
  39. render() {
  40. return (
  41. <GeneratedComponentClass
  42. {...this.state.allProps}
  43. componentId={this.state.componentId}
  44. />
  45. );
  46. }
  47. private _assertComponentId() {
  48. if (!this.props.componentId) {
  49. throw new Error(`Component ${componentName} does not have a componentId!`);
  50. }
  51. }
  52. }
  53. polyfill(WrappedComponent);
  54. hoistNonReactStatics(WrappedComponent, concreteComponentProvider());
  55. return ReduxProvider ? this.wrapWithRedux(WrappedComponent, ReduxProvider, reduxStore) : WrappedComponent;
  56. }
  57. wrapWithRedux(WrappedComponent: React.ComponentClass<any>, ReduxProvider: any, reduxStore: any): React.ComponentClass<any> {
  58. class ReduxWrapper extends React.Component<any, any> {
  59. render() {
  60. return (
  61. <ReduxProvider store={reduxStore}>
  62. <WrappedComponent {...this.props} />
  63. </ReduxProvider>
  64. );
  65. }
  66. }
  67. hoistNonReactStatics(ReduxWrapper, WrappedComponent);
  68. return ReduxWrapper;
  69. }
  70. }