【问题标题】:Private Route with React and Axios.get使用 React 和 Axios.get 的私有路由
【发布时间】:2022-08-12 00:54:11
【问题描述】:

我试图创建一条私人路线,如果我没有登录,它将重定向到登录,如果没有,那么它将带我回家,但我正在努力让它工作

我的 privateRoute.js

import React, { useState, useEffect } from \'react\'
import { Navigate, useNavigate } from \"react-router-dom\"
import Axios from \'axios\'
import Home from \"./home/home.js\"

const PrivateRoute = ({ children }) => {

    Axios.defaults.withCredentials = true;
    const navigate = useNavigate();
    useEffect(()=> {
        Axios.get(\"http://localhost:3001/login\").then((response) => {
            if (response.data.loggedIn === true) {
                console.log(\"HOME\")
                return (
                    <>
                        <Home/>
                    </>
                )
                
            } else {
                navigate(\"/\" , {replace: true})
            }
        })
    },[])
}

export default PrivateRoute

我的 App.js

import React from \'react\'
import { Route, Routes } from \"react-router-dom\"

// COMPONENTS
import Login from \'./login/login.js\'
import Home from \'./home/home.js\'
import PrivateRoute from \'./PrivateRoute.js\'

// STYLE
import \'./login/login.css\'
import \'./register/register.css\'
import \'./App.css\'


const App = () => {
    return (
        <>
            <Routes>
                <Route exact path=\"/\" element={<Login/>}></Route>
            
                <Route exact path=\"/home\" element={
                    <PrivateRoute>
                        <Home/>
                    </PrivateRoute>

                }></Route>
            </Routes>
        </>
    )
}
export default App

    标签: reactjs axios


    【解决方案1】:

    您正尝试从 useEffect 返回 ReactNode

    useEffectreturn 用作清理功能,在组件卸载时或在下次执行 useEffect 之前运行。

    例子:

    useEffect(() => {
        // set a timer to show an alert in 20 seconds.
        const timeoutId = setTimeout(() => alert('I\'m a cool kid!'), 20000);
    
        return () => {
            // clear the timer if the component is unmounted so that the 
            // alert will no longer trigger
            clearTimeout(timeoutId);
        }
    }, [])
    

    要解决您的问题,您的 PrivateRoute 组件将需要返回您希望它呈现的内容:

    import React, { useState, useEffect } from 'react'
    import { Navigate, useNavigate } from "react-router-dom"
    import Axios from 'axios'
    import Home from "./home/home.js"
    
    const PrivateRoute = ({ children }) => {
        // state to store whether the auth check has completed.
        const [loading, setLoading] = useState(true);
    
        // state to store whether the user is authenticated
        const [loggedIn, setLoggedIn] = useState(false);
    
        // state to store any error encounted while running the auth check.
        const [error, setError] = useState();
    
        Axios.defaults.withCredentials = true;
    
        const navigate = useNavigate();
    
        useEffect(()=> {
            // create async function to avoid the use of promise .then spam
            // this is just a preference coming from C# background prefer the 
            // async / await syntax.
            const checkLogin = async () => {
                try {
                    // run the auth check.
                    const response = await Axios.get("http://localhost:3001/login");
        
                    // set whether the user is logged in.
                    setLoggedIn(!!response?.data?.loggedIn)
    
                    // set that no error was encountered.
                    setError(undefined);
    
                    // start redirection if not logged in.
                    if (!response?.data?.loggedIn) {
                        navigate("/" , {replace: true});
                    }
                }
                // catch any error with the request.
                catch (err) {
                    // set user to not logged in.
                    setLoggedIn(false);
    
                    // set the error to the caught exception.
                    setError(err);
    
                    // add another redirect call if you don't want to display an error when the request fails
                    // e.g.: navigate("/" , {replace: true});
                }
    
                // request is finished set loading to false.
                setLoading(false);
            };
    
            checkLogin();
        }, [setLoading, setError, setLoggedIn])
    
        // This is the view while the auth check is being carried out:
        if (loading) {
            return (
                <>
                    I am checking auth status...
                </>
            );
        }
    
        // This is the view if the auth check encounters an error:
        if (error) {
            return (
                <pre>
                    {JSON.stringify(error, null, '\t')}
                </pre>
            );
        }
    
        // This is the view if the user was not authenticated
        // As the redirect is started as part of the useEffect this will
        // most likely not be displayed for any significant (or even preceivable)
        // amount of time.
        if (!loggedIn) {
            return (
                <>
                    I am redirecting...
                </>
            );
        }
    
        // This is the view if the user was authenticated.
        // Example view below renders the child elements that have been provided i.e. <Home /> in your snippet.
        return (
            <>
                {children}
            </>
        )
    }
    
    export default PrivateRoute
    

    【讨论】:

    • 感谢先生如此清晰详细的解释!它帮助我现在更好地理解它
    【解决方案2】:

    请试试这个

    import React, { useState, useEffect } from 'react'
    import { Navigate, useNavigate } from "react-router-dom"
    import Axios from 'axios'
    import Home from "./home/home.js"
    
    const PrivateRoute = ({ children }) => {
    
        Axios.defaults.withCredentials = true;
        const navigate = useNavigate();
        
        const [loggedIn, setLoggedIn] = useState(false);
        useEffect(()=> {
            Axios.get("http://localhost:3001/login").then((response) => {
                if (response.data.loggedIn === true) {
                    setLoggedIn(true);
                } else {
                    navigate("/" , {replace: true})
                }
            })
        },[])
    
        if (!loggedIn) {
            return (
                <>
                    Loading...
                </>
            )
        }
    
        return (
            <>
                <Home/>
                // Or {...children}
            </>
        )
    }
    

    【讨论】:

    • 这解决了我的问题!非常感谢兄弟,我一整天都在想办法:D
    猜你喜欢
    • 2020-08-13
    • 1970-01-01
    • 2018-03-05
    • 2022-01-17
    • 1970-01-01
    • 2021-06-04
    • 2020-07-03
    • 2018-11-05
    • 2020-06-26
    相关资源
    最近更新 更多