@eolme/vma-router
Version:
Router for VK Mini Apps
49 lines (48 loc) • 2.19 kB
JavaScript
import React from 'react';
import { useContext, useState, useRef, useEffect, useCallback, timers } from '@eolme/vma-engine';
import { RouterContext } from '../components/RouterContext';
import { error } from '../utils/report';
const MAGIC_UPDATE_INTERVAL = 650;
export function withTransitionRouter(Component) {
const withTransitionRouter = (props) => {
/* eslint-disable react-hooks/rules-of-hooks */
const router = useContext(RouterContext);
if (!router) {
error('Missing router context!');
return null;
}
const lastUpdateRouteAt = useRef(0);
const updateTimer = useRef(0);
const updateCallback = useRef(null);
const [route, setRoute] = useState(router.history.route);
useEffect(() => {
const fn = (event) => {
const diff = Date.now() - lastUpdateRouteAt.current;
if (diff >= MAGIC_UPDATE_INTERVAL) {
lastUpdateRouteAt.current = Date.now();
setRoute(event.next);
}
else {
timers.clearTimeout(updateTimer.current);
updateCallback.current = () => {
lastUpdateRouteAt.current = Date.now();
setRoute(event.next);
updateCallback.current = null;
};
updateTimer.current = timers.setTimeout(updateCallback.current, MAGIC_UPDATE_INTERVAL - diff);
}
};
router.history.on('update', fn);
return () => {
router.history.off('update', fn);
};
}, [router]);
const onTransitionEnd = useCallback(() => {
lastUpdateRouteAt.current = 0;
}, []);
return (React.createElement(Component, Object.assign({}, props, { onTransitionEnd: onTransitionEnd, route: route })));
};
const displayName = Component.displayName || Component.name || 'Component';
withTransitionRouter.displayName = `withTransitionRouter(${displayName})`;
return withTransitionRouter;
}