使用React Router设置专用路由

时间:2019-11-07 14:44:10

标签: javascript reactjs react-router react-router-dom

我正在尝试使用反应路由器dom建立一个具有未授权用户登录屏幕和授权用户仪表板的网站。

例如,每次用户单击侧边栏中的链接时,都会发生路线更改(仪表板路线)。仪表板组件内部的useEffect被调用,它获取我已经拥有的数据。


## ROUTES ##

export const appRoutes = auth => [
    {
        path: '/',
        component: () => auth ? <Redirect to='/dashboard' /> :<Login/>,
        exact: true
    },
    {
        path: '/dashboard',
        component: Guilds ## REDIRECTS TO THE NEXT ROUTE WITH ID ##,
        exact: true,
        private: true
    },
    {
        path: '/dashboard/:id',
        component: Dashboard,
        private: true
    },
    {
        path: '/dashboard/*',
        component: Dashboard,
        private: true
    }
]

export const dashboardRoutes = [
    {
        path: '/dashboard/:id',
        component: Home,
        exact: true
    }
]

## SIMPLIFIED APP COMPONENT ##

export default function App() {
    return (
        <ThemeProvider theme={theme}>
            <BrowserRouter>
                <Switch>
                    {appRoutes(auth).map(value => {
                        if(value.private) return <PrivateRoute path={value.path} component={value.component} exact={value.exact} key={value.path} auth={auth} />;
                        else return <Route path={value.path} component={value.component} exact={value.exact} key={value.path} />;
                    })}
                </Switch>
            </BrowserRouter>
        </ThemeProvider>
    )
}

## SIMPLIFIED DASHBOARD COMPONENT ## 

export default function Dashboard({ match }) {
    const [guild, setGuild] = useState(null);
    const [user, setUser] = useState(null);

    useEffect(() => {
        getGuild(match.params.id)
        .then(res => {
            setGuild(res.data);
            return getUser();
        })
        .then(res => {
            setUser(res.data);
        })
        .catch(err => {
            console.log(err);
        })
    }, [match.params.id]);

    return (
        <div className={classes.root}>
            <Header onToggleDrawer={onToggleDrawer} guild={guild} auth />
            <SideBar onToggleDrawer={onToggleDrawer} isOpen={drawerOpen} user={user} />
            <div className={classes.content}>
                <div className={classes.toolbar} />
                <div className={classes.contentContainer}>
                    {dashboardRoutes.map(value => {
                        return <Route exact={value.exact} path={value.path} component={value.component} key={value.path}/>
                    })}
                </div>
            </div>
        </div>
    )
}

## PRIVATE ROUTE COMPONENT ##

export const PrivateRoute = ({ component: Component, auth, ...rest }) => {
    return (
        <Route {...rest} render={(props) => (
            auth
                ? <Component {...props} />
                : <Redirect to='/' />
        )} />
    )
}

我不确定我是否能正确处理这种情况,但是任何帮助都会很大。我认为该功能被称为,以防万一用户从书签访问该网站,但前提是有人可以发出一些很棒的信息。

谢谢。

1 个答案:

答案 0 :(得分:0)

获取多次发生的原因是依赖数组useEffect具有什么。我假设match.params.id在用户单击时发生了变化,然后它更改了将再次触发提取的路由。

可能的解决方案:

1。空的依赖项数组:

一种可能的解决方案是,如果您只想将数据设置为useEffect的依赖项数组为空,则仅获取数据。来自documentation

  

如果要运行效果并仅将其清理一次(在挂载和卸载时),则可以将空数组([])作为第二个参数传递。这告诉React,您的效果不依赖于道具或状态的任何值,因此它不需要重新运行。

因此,如果您具有以下内容,它将仅运行一次:

useEffect(() => {
   // this part runs only once
}, []); // empty dependency array

2。检查抓取是否已经发生:

我在想的另一种解决方案是检查guild变量中是否已经有值,如下所示:

useEffect(() => {
    // no value presented for guild
    if (guild === null) {
       // code which is running the fetch part
    }
}, [match.params.id]);

希望这对您有所帮助!