Advertisement
Guest User

Untitled

a guest
Oct 28th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.36 KB | None | 0 0
  1. // this `<Route>` component might make it possible for you to ~generally~
  2. // upgrade to React Router v4 w/o doing hardly anything to your app for the
  3. // happy path stuff.
  4. //
  5. // This definitely won't work as-is, I haven't run this code, just banged it
  6. // out when the thought occured to me that it might be possible.
  7.  
  8. const { func, object } = React.PropTypes
  9.  
  10. const Route = (route) => (
  11. <Match pattern={route.path} render={(props) => (
  12. route.children ? (
  13. <MatchWithRouteLifecycle route={route} {...props}>
  14. <MatchGroup>
  15. {React.Children.map(children, (child) => (
  16. <Route {...child.props}/>
  17. ))}
  18. </MatchGroup>
  19. </Component>
  20. ) : (
  21. <MatchWithRouteLifecycle route={route} {...props}/>
  22. )
  23. )}/>
  24. )
  25.  
  26. class MatchWithRouteLifecycle extends React.Component {
  27. static propTypes = {
  28. route: {
  29. component: func,
  30. getComponent: func,
  31. onEnter: func,
  32. onChange: func,
  33. onLeave: func,
  34.  
  35. components: object, // NOPE
  36. getComponents: func, // NOPE
  37. getChildRoutes: func // NOPE
  38. },
  39. location: object,
  40. path: string,
  41. pattern: string
  42. }
  43.  
  44. constructor(props) {
  45. super(props)
  46. this.state = {
  47. prevProps: null,
  48. needingToRunEnterHook: props.route.onEnter,
  49. needingToGetComponent: props.route.getComponent,
  50. AsyncComponent: null
  51. }
  52. }
  53.  
  54. componentDidMount() {
  55. if (this.state.needingToRunEnterHook) {
  56. this.runEnterHook()
  57. }
  58. if (this.state.needingToGetComponent) {
  59. this.getComponent()
  60. }
  61. }
  62.  
  63. componentWillReceiveProps(nextProps) {
  64. if (!locationsAreEqual(nextProps.location, this.props.location)) {
  65. if (this.props.onChange) {
  66. this.runChangeHook(nextHook)
  67. }
  68. }
  69. }
  70.  
  71. componentWillUnmount() {
  72. if (this.props.route.onLeave) {
  73. this.runLeaveHook()
  74. }
  75. }
  76.  
  77. getComponent() {
  78. this.props.route.getComponent((err, AsyncComponent) => {
  79. this.setState({ AsyncComponent })
  80. })
  81. }
  82.  
  83. runLeaveHook() {
  84. const prevState = {}
  85. this.props.route.onLeave(prevState)
  86. }
  87.  
  88. runEnterHook() {
  89. const { onEnter } = this.props.route
  90. const isAsync = onEnter.length === 3
  91. const nextState = {}
  92. const replace = () => {}
  93. if (isAsync) {
  94. onEnter(nextState, replace, () => {
  95. this.setState({ needingToRunEnterHook: false })
  96. })
  97. } else {
  98. onEnter(nextState, replace)
  99. this.setState({ needingToRunEnterHook: false })
  100. }
  101. }
  102.  
  103. runChangeHook(nextProps) {
  104. const { onChange } = this.props
  105. const isAsync = onChange.length === 4
  106. const prevState = {}
  107. const nextState = {}
  108. const replace = () => {}
  109. if (!isAsync) {
  110. onChange(prevState, nextState, replace)
  111. } else {
  112. this.block(() => {
  113. onChange(prevState, nextState, replace, this.unblock)
  114. })
  115. }
  116. }
  117.  
  118. block(cb) {
  119. this.setState({ prevProps: this.props }, cb)
  120. }
  121.  
  122. unblock() {
  123. this.setState({ prevProps: null })
  124. }
  125.  
  126. render() {
  127. if (
  128. this.state.needingToRunEnterHook ||
  129. this.state.needingToGetComponent
  130. ) {
  131. return null
  132. } else {
  133. const props = this.state.prevProps ?
  134. this.state.prevProps : this.props
  135. const { route, params, location, children } = props
  136. const Component = this.state.AsyncComponent || route.props.component
  137. const v3Props = { ...route, params, location, children }
  138. return <Component {...v3Props}/>
  139. }
  140. }
  141. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement