I'm updating a react project's packages which had been implemented with react-router-dom v5. I've updated react-router-dom to v6. I've used this.props.history in a lot of components and because of that I don't need to change its structure, so I decided to create a wrapper which has that functionality and pass the components to it as a prop to don't change a lot of code. Here's the wrapper:
import * as React from 'react';
import { useLocation, useNavigate, useNavigationType, useParams } from "react-router";
export function withRouter(Child) {
return (props) => {
const [callBack,setCallBack] = React.useState();
const location = useLocation();
const navigate = useNavigate();
const action = useNavigationType();
const params = useParams();
const match = {
params: params
}
const history = {
push: (url, onMount) => {
if (onMount)
setTimeout(() => navigate(url), 100)
else
navigate(url);
},
listen: (callback) => {
setCallBack(callback);
}
}
React.useEffect(() => {
if (callBack) {
callBack(location,action)
}
}, [location])
return <Child {...props} history={history} location={location} match={match} />;
}
}
I've used my wrapper in a component like this:
function action(params) {
return (
<Layout {...params}>
<PageInfo title={Utils.i18n('notificationList', true)} icon="ti-bell"/>
<NotificationList {...params}/>
</Layout>
)
}
export default withRouter(action);
And Here's the listen function on componentDidMount of the wrapped component:
componentDidMount(): void {
this.props.history.listen((location, action) => {
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
if (params.id) {
this.setState({id:params.id})
}
});
this.getNotification();
Utils.scrollToTop();
}
My problem in this updating is listen functionality which was existed in react-router-dom v5. Because after any state change in Child prop, all states cleared, so callBack is always undefined and I couldn't implement listen functionality in my wrapper. In this part of code, callback is always undefined:
React.useEffect(() => {
if (callBack) {
callBack(location,action)
}
}, [location])
Does anyone have any idea to implement listen functionality in my wrapper?