react-native-navigation的迁移库

ComponentWrapper.tsx 2.5KB

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