react-native-navigation的迁移库

ComponentWrapper.tsx 2.8KB

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