1import { useCallback, useMemo, useState, useRef, useEffect } from 'react';
2import { last, includes as _includes, findIndex } from 'lodash';
7 * @param names map of string to view key, used for consumer references
8 * @param views map of view keys to react component views
9 * @param initialRoutes initial set of routes following the { key, data } format
11export default function useRouter({
16 const [routes, setRoutes] = useState(initialRoutes);
18 const oldPopState = useRef();
20 const size = routes.length;
21 const push = useCallback(
25 `Invalid Route: ${key}. Possible Routes: ${Object.keys(views).join(
30 setRoutes(routes => [...routes, { key, data }]);
34 const popAndPush = useCallback(
38 `Invalid Route: ${key}. Possible Routes: ${Object.keys(views).join(
45 ...routes.slice(0, routes.length - 1),
51 const pop = useCallback(
54 // if we are at the root, pass this event to our parent
55 if (oldPopState.current) {
56 console.log('attempting to pass to parent');
57 window.history.back();
60 console.log('at root');
65 // on pop, tell the browser of a new state to avoid giving the user
66 // the ability to go forward
67 // TODO: allow the user to go forward by storing our data in history
68 // and using the url for other state
69 // (or just importing an actually good router lib)
70 window.history.pushState(null, null, null);
73 return setRoutes(routes => [...routes.slice(0, routes.length - count)]);
75 [size, setRoutes, oldPopState]
77 const popTo = useCallback(
79 const index = findIndex(routes, route => route.key === name);
80 return pop(routes.length - 1 - index);
84 const peek = useCallback(() => last(routes), [routes]);
85 const replaceWith = useCallback(routes => setRoutes(() => routes), [
88 const reset = useCallback(() => setRoutes(initialRoutes), [
92 const includes = useCallback(key => _includes(routes.map(r => r.key), key), [
95 const data = useMemo(() => last(routes).data || NULL_DATA, [routes]);
96 const Route = useMemo(() => views[peek().key], [views, peek]);
98 // Scroll to top of page with each route transition
100 window.scrollTo(0, 0);
104 // on router mount, register new state with browser
105 window.history.pushState(null, null, null);
108 // capture browser pop in primary router
110 // store the previous onpopstate handler
111 oldPopState.current = window.onpopstate;
113 // construct new onpopstate handler
114 window.onpopstate = e => {
115 e.stopImmediatePropagation();
120 // reset the onpopstate to the previous version
121 window.onpopstate = oldPopState.current;
123 }, [size, pop, oldPopState]);
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list