【问题标题】:Setting up private routes with react router使用反应路由器设置私有路由
【发布时间】:2020-03-04 04:17:57
【问题描述】:

我正在尝试设置一个网站,其中包含未授权用户的登录屏幕和使用反应路由器 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='/' />
        )} />
    )
}

我不确定我是否正确处理了这种情况,但任何帮助都会很棒。我认为这个函数会被调用,以防用户从书签访问该网站,但如果有人能提供一些启发,那就太酷了。

谢谢。

【问题讨论】:

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


    【解决方案1】:

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

    可能的解决方案:

    1.空依赖数组:

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

    如果你想运行一个效果并且只清理一次(在挂载和卸载时),你可以传递一个空数组([])作为第二个参数。这告诉 React 你的效果不依赖于任何来自 props 或 state 的值,所以它永远不需要重新运行。

    所以如果你有以下,它只会运行一次:

    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]);
    

    我希望这能给你一个想法和帮助!

    【讨论】:

    • 有时我会沉迷于这些东西,以至于忘记尝试最基本的东西。我会试试看效果如何!
    • 每个人都会遇到这种情况。 :) 请告诉我进展如何,谢谢!
    猜你喜欢
    • 2021-01-03
    • 2023-04-07
    • 2018-11-05
    • 1970-01-01
    • 2020-10-22
    • 2020-08-24
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多