Last active
July 27, 2019 05:52
-
-
Save iShawnWang/fddaa66f0090133fd8d42cc363a7e6d4 to your computer and use it in GitHub Desktop.
react-router backward hooks, support react-router 4.x | 5.x
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { __RouterContext as RouterContext, RouteComponentProps } from 'react-router' | |
import { useContext, useMemo, useCallback } from 'react' | |
import qs from 'qs' | |
import { Location } from 'history' | |
interface ParsedQuery { | |
[whatever: string]: any | |
} | |
export const useRouter = <T>(): RouteComponentProps<T> => | |
useContext(RouterContext) as RouteComponentProps<T> | |
export const useLocation = (): Location => { | |
const { location } = useRouter() | |
return location | |
} | |
export const useParams = <T>(): T => { | |
const { location } = useRouter<T>() | |
// @ts-ignore | |
return location.query | |
} | |
export const useQuery = <T extends ParsedQuery>(): T => { | |
// @ts-ignore | |
const { query } = useLocation() | |
const q = useMemo(() => qs.parse(query), [query]) | |
return q as T | |
} | |
export const useUpdateQuery = <T extends ParsedQuery>() => { | |
const { history } = useRouter() | |
const query = useQuery<T>() | |
const updateQuery = useCallback( | |
(patch: Partial<T>, merge = true): void => { | |
const newQuery = merge ? { ...query, ...patch } : patch | |
const newSearch = qs.stringify(newQuery) | |
history.push({ search: newSearch }) | |
}, | |
[history, query], | |
) | |
return updateQuery | |
} | |
export const useRouterBackward = <T>(r: RouteComponentProps<T>): RouteComponentProps<T> => | |
r as RouteComponentProps<T> | |
export const useLocationBackward = (r: RouteComponentProps<T>): Location => { | |
const { location } = useRouterBackward(r) | |
return location | |
} | |
export const useParamsBackward = <T>(r: RouteComponentProps<T>): T => { | |
const { location } = useRouterBackward<T>(r) | |
// @ts-ignore | |
return location.query | |
} | |
export const useQueryBackward = <T extends ParsedQuery>(r: RouteComponentProps<T>): T => { | |
// @ts-ignore | |
const { query } = useLocationBackward(r) | |
const q = useMemo(() => qs.parse(query), [query]) | |
return q as T | |
} | |
export const useUpdateQueryBackward = <T extends ParsedQuery>(r: RouteComponentProps<T>) => { | |
const { history } = useRouterBackward(r) | |
const query = useQueryBackward<T>(r) | |
const updateQuery = useCallback( | |
(patch: Partial<T>, merge = true): void => { | |
const newQuery = merge ? { ...query, ...patch } : patch | |
const newSearch = qs.stringify(newQuery) | |
history.push({ search: newSearch }) | |
}, | |
[history, query], | |
) | |
return updateQuery | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
for react-router 4.x:
for react-router 5.x :
Just call
useRouter
,useLocation
,useQuery
function without backward suffix