UNPKG

react-router-config-guard

Version:

Static route config and guard for React Router, base on react-router-config

174 lines (147 loc) 6.09 kB
import React from "react"; import { Redirect, Route } from "react-router"; import { useState, useContext } from "react"; import { memo, useCallback, useEffect } from "react" import { __RouterContext as RouterContext } from 'react-router'; import { FromRouteContext } from './Contexts.jsx'; // const from = createContext(FromRouteContext); // const to = createContext(RouterContext); // class RouterGuard2 extends React.PureComponent { // hasRouteGuard // guardToRedirect = false; // isRedirect = false; // redirectPath = ""; // constructor(props) { // super(props); // this.hasRouteGuard = !!this.props.routerBeforeEach; // this.state = { // routeGuardFinished: false, // } // } // getTo() { // return { ...to, meta: this.props.route.meta || {}, route: this.props.route } // } // componentDidMount() { // if (!this.hasRouteGuard) { // return; // } // this.props.routerBeforeEach(this.getTo(), from, (to) => { // if (!to) { // this.guardToRedirect = false; // this.setState({ // routeGuardFinished: true // }) // } else { // if (typeof to === 'string') { // this.redirectPath = to; // this.isRedirect = false; // this.guardToRedirect = true; // this.setState({ // routeGuardFinished: true // }) // } else if (typeof to === 'object' && (typeof to.path === 'string' || typeof to.name === 'string')) { // this.redirectPath = to.path || to.name; // this.isRedirect = to.replace || false; // this.guardToRedirect = false; // this.setState({ // routeGuardFinished: true // }) // } else { // console.log(`Your next format is incorrect, should be : next('/') or next({ path: '/' }) or next({ path: '/', replace: true})`); // this.guardToRedirect = false; // this.setState({ // routeGuardFinished: true // }) // } // } // }) // } // render() { // var { routerAfterEach, route, history } = this.props // if (!this.state.routeGuardFinished) { // return null; // } // if (this.guardToRedirect && this.redirectPath) { // routerAfterEach && routerAfterEach(this.getTo()); // if (this.isRedirect) { // return <Redirect to={this.redirectPath} {...this.props} /> // } else { // if (history) { // history.push(this.redirectPath); // return null; // } else { // return <Route to={this.redirectPath} {...this.props} /> // } // } // } // routerAfterEach && routerAfterEach(this.getTo()); // return React.createElement(route.component, this.props); // } // } const RouterGuard = memo(function (props) { // console.log("init RouterGuard"); var { routerBeforeEach, routerAfterEach, route, history } = props const from = useContext(FromRouteContext); const to = useContext(RouterContext); const getTo = useCallback(() => { return { ...to, meta: route.meta || {}, route } }, [to, route]) // const hasRouteGuard = !!routerBeforeEach; const [routeGuardFinished, setRouteGuardFinished] = useState(false); const [redirectPath, setRedirectPath] = useState(""); const [guardToRedirect, setGuardToRedirect] = useState(false); const [isRedirect, setIsRedirect] = useState(false); const hook = useCallback((to, from, next) => { routerBeforeEach && routerBeforeEach(to, from, next); }, [routerBeforeEach]) useEffect(() => { if (!routerBeforeEach) { setRouteGuardFinished(true); setGuardToRedirect(false); } else { hook(getTo(), from, (to) => { if (!to) { setGuardToRedirect(false); setRouteGuardFinished(true); } else { // next('/') or next({ path: '/' }) -> redirect if (typeof to === 'string') { setRedirectPath(to); setIsRedirect(false); setGuardToRedirect(true); setRouteGuardFinished(true); } else if (typeof to === 'object' && (typeof to.path === 'string' || typeof to.name === 'string')) { setRedirectPath(to.path || to.name); setIsRedirect(to.replace || false); setGuardToRedirect(true); setRouteGuardFinished(true); } else { console.log(`Your next format is incorrect, should be : next('/') or next({ path: '/' }) or next({ path: '/', replace: true})`); setGuardToRedirect(false); setRouteGuardFinished(true); } } }) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [hook]) if (!routeGuardFinished) { return null; } if (guardToRedirect && redirectPath) { routerAfterEach && routerAfterEach(getTo()); if (isRedirect) { return <Redirect to={redirectPath} {...props} /> } else { if (history) { history.push(redirectPath); return null; } else { return <Route to={redirectPath} {...props} /> } } } routerAfterEach && routerAfterEach(getTo()); return React.createElement(route.component, props); }) export default RouterGuard;