Skip to content

Commit

Permalink
Merge pull request #10 from space-fe/hook
Browse files Browse the repository at this point in the history
fix: use react hook instead of componentWillReceiveProps
  • Loading branch information
XiaocongDong authored Sep 5, 2019
2 parents c4eb0e3 + c70aa9b commit 99ecc97
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 32 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-onroutechanged",
"version": "1.0.0",
"version": "1.0.1",
"description": "An onRouteChanged wrapper for React components",
"main": "es/index.js",
"types": "types/index",
Expand Down
61 changes: 30 additions & 31 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React from 'react'
import PropTypes from 'prop-types'
import { withRouter } from 'react-router-dom'

const { useEffect, useRef } = React

/**
* This function generates the HOC function that will call
* the handleRoutedChanged function of the DecoratedComponent instance
Expand All @@ -14,33 +16,31 @@ const onRouteChangedHOC = (DecoratedComponent, config = { mounted: false, onlyPa
const componentName = DecoratedComponent.displayName || DecoratedComponent.name || 'Component'
const isReactComponent = DecoratedComponent.prototype && DecoratedComponent.prototype.isReactComponent

class RouteChangedComponent extends React.Component {
static displayName = `OnRouteChanged(${componentName})`

static propTypes = {
location: PropTypes.object.isRequired
}
const RouteChangedComponent = (props) => {
const { location } = props
const prevLocationRef = useRef(location)
const instanceRef = useRef(null)

__getHandleRouteChangedFunc = () => {
const __getHandleRouteChangedFunc = () => {
let handleRouteChanged

if (!isReactComponent && typeof config.handleRouteChanged === 'function') {
handleRouteChanged = config.handleRouteChanged
}

if (isReactComponent && typeof this.instanceRef.handleRouteChanged === 'function') {
handleRouteChanged = this.instanceRef.handleRouteChanged
if (isReactComponent && typeof instanceRef.current.handleRouteChanged === 'function') {
handleRouteChanged = instanceRef.current.handleRouteChanged
}

return handleRouteChanged
}

__routeChangedHandler = (prevLocation, nextLocation) => {
const __routeChangedHandler = (prevLocation, nextLocation) => {
const isSamePath = prevLocation.pathname === nextLocation.pathname
const isSameSearch = prevLocation.search === nextLocation.search
const isSameHash = prevLocation.hash === nextLocation.hash

const handleRouteChanged = this.__getHandleRouteChangedFunc()
const handleRouteChanged = __getHandleRouteChangedFunc()

if (!isSamePath) {
return handleRouteChanged(prevLocation, nextLocation)
Expand All @@ -51,43 +51,42 @@ const onRouteChangedHOC = (DecoratedComponent, config = { mounted: false, onlyPa
}
}

componentDidMount () {
const handleRouteChanged = this.__getHandleRouteChangedFunc()
useEffect(() => {
const handleRouteChanged = __getHandleRouteChangedFunc()

if (typeof handleRouteChanged !== 'function') {
throw new Error(
'WrappedComponent lacks a handleRouteChanged(prevLocation, currLocation) for processing route changed event.'
)
}

if (config.mounted) {
// Since we have no idea what the previous route is when the component got mounted,
// We will pass an null as the prevLocation param
handleRouteChanged(null, this.props.location)
}
}

componentWillReceiveProps (nextProps) {
const prevLocation = this.props.location
const nextLocation = nextProps.location

if (prevLocation === nextLocation) {
return
handleRouteChanged(null, location)
}
}, [])

this.__routeChangedHandler(prevLocation, nextLocation)
}
useEffect(() => {
prevLocationRef.current = location
})
const preLocation = prevLocationRef.current

render () {
let { ...props } = this.props
if (isReactComponent) {
props.ref = ref => { this.instanceRef = ref }
}
useEffect(() => {
__routeChangedHandler(preLocation, location)
}, [props.location])

if (isReactComponent) {
return <DecoratedComponent ref={instanceRef} {...props} />
} else {
return <DecoratedComponent {...props} />
}
}

RouteChangedComponent.propTypes = {
location: PropTypes.object.isRequired
}
RouteChangedComponent.displayName = `OnRouteChanged(${componentName})`

return withRouter(RouteChangedComponent)
}

Expand Down

0 comments on commit 99ecc97

Please sign in to comment.