diff --git a/package.json b/package.json index 47accb6..ca2e667 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/index.js b/src/index.js index 6129641..09228cb 100644 --- a/src/index.js +++ b/src/index.js @@ -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 @@ -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) @@ -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 + } else { return } } + RouteChangedComponent.propTypes = { + location: PropTypes.object.isRequired + } + RouteChangedComponent.displayName = `OnRouteChanged(${componentName})` + return withRouter(RouteChangedComponent) }