如果用户已登录 Reactjs,则显示或隐藏组件

Show or hide component if user is logged in Reactjs

我已经设置了注册和登录页面...使用 nodejs express jwt,令牌保存在 cookie 中。我的目标是检查用户是否登录,然后在导航栏中显示或隐藏元素。到目前为止,这就是我带来的。这个解决方案的问题是我必须刷新浏览器,因为我必须发出条件渲染的获取请求才能工作。请帮忙


function Navbar() {
    const [visible, setVisible] = useState(false);
    const navigate = useNavigate();
    const[isLoggedIn, setIsLoggedIn] = useState(false)

    useEffect(() => {
       checkLogin()
    }, []);


    const checkLogin = async () => {
        try {
            await axios.get('http://localhost:5000/token', {withCredentials: true});
            setIsLoggedIn(true)
        } catch (e) {
            setIsLoggedIn(false)
            console.log(e)
        }


    }


    const Logout = async () => {
        try {
            await axios.delete('http://localhost:5000/logout', {withCredentials: true});
            navigate("/");
        } catch (error) {
            console.log(error);
        }
    }

    const showDrawer = () => {
        setVisible(true);
    };

    const onClose = () => {
        setVisible(false);
    };


    return (
        <div className="menu">
            <Link to='/'>

                <div className="logo"/>
            </Link>
            {!isLoggedIn? (

                <Menu theme="dark" mode='horizontal' disabledOverflow='true'>
                    <Menu.Item><Link to='/login'>Log In</Link></Menu.Item>
                    <Menu.Item><Link to='signup'>Sign Up</Link></Menu.Item>
                </Menu>
            ) : (

                <Button className='logout' onClick={Logout}>Log out</Button>
            )}

            <Button className="barsMenu" type="primary" onClick={visible ? onClose : showDrawer}>
                <span className="barsBtn"/>
            </Button>
            <Drawer
                placement="bottom"
                closable={false}
                onClose={onClose}
                visible={visible}
                closeIcon
            >
                <Link to='/login'>
                    <Button onClick={onClose}>Log in</Button>
                </Link>
                <Link to='/signup'>
                    <Button onClick={onClose}>Sign up</Button>
                </Link>
            </Drawer>
        </div>
    )
}

export default Navbar

更新: 这是我的登录组件



const LoginForm = () => {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [msg, setMsg] = useState('');
    const navigate = useNavigate();

    const onFinish = async () => {
        try {
            await axios.post('http://localhost:5000/login', {
                email: email,
                password: password
            },{withCredentials:true})
            navigate('/profile')
        } catch (error) {
            if (error.response) {
                setMsg(error.response.data.msg)
                console.log(error)

            }
        }
    };

    return (
        <div className='login-form-landing'>
            <div className="login-form-inner">
                <Form
                    name="normal_login"
                    className="login-form"
                    initialValues={{
                        remember: true,
                    }}
                    onFinish={onFinish}
                >
                    <Form.Item>
                        <Button className='facebook-button'>Continue with Facebook</Button>
                    </Form.Item>
                    <Form.Item>
                        <Button className='google-button'>Continue with Google</Button>
                    </Form.Item>
                    <Form.Item
                        name="email"
                        value={email}
                        onChange={(e)=>setEmail(e.target.value)}
                        rules={[
                            {
                                required: true,
                                message: 'Please input your email!',
                            },
                        ]}
                    >
                        <Input prefix={<UserOutlined className="site-form-item-icon"/>} placeholder="email"/>
                    </Form.Item>
                    <Form.Item
                        name="password"
                        value={password}
                        onChange={(e)=>setPassword(e.target.value)}
                        rules={[
                            {
                                required: true,
                                message: 'Please input your Password!',
                            },
                        ]}
                    >
                        <Input
                            prefix={<LockOutlined className="site-form-item-icon"/>}
                            type="password"
                            placeholder="Password"
                        />
                    </Form.Item>
                    <Form.Item>
                        <Form.Item name="remember" valuePropName="checked" noStyle>
                            <Checkbox>Remember me</Checkbox>
                        </Form.Item>

                        <a className="login-form-forgot" href="">
                            Forgot password
                        </a>
                    </Form.Item>

                    <Form.Item>
                        <Button type="primary" htmlType="submit" className="login-form-button form-submit">
                            Log in
                        </Button>
                        <div className="or-link">
                            <span>Or</span>
                            <Link to='/signup'>register now!</Link>
                        </div>
                    </Form.Item>
                </Form>
            </div>
        </div>
    );
};

export default LoginForm


isAuth、token 等状态可以存储在 Cookie 或 local/session 存储中,状态管理应该使用 Context API 这样当页面刷新时状态不会丢失

const LoginContext = createContext({isAuth:false,token : "", 
                                    setAuth: () => {}})

const LoginProvider = ({child}) => {
   const [isAuth,setAuth] = useState(localStorage.getItem("isAuth") || false)
   const [token, setToken] = useState(localStorage.getItem("token"))
   useEffect(() => {
      localStorage.setItem("isAuth",isAuth)
   },[isAuth])
   return (
        <LoginContext.Provider value={{isAuth,token,setAuth}}>
             {child}
        </LoginContext.Provider>
      )
    }

登录时

const {isAuth, setAuth}= useContext(LoginContext)
const login = async () => {
   var result = await axios.get('http://localhost:5000/token', {withCredentials: true});
   var { data} = result.data;
   setAuth(data != null) //or conditional state

}
const logout = async () => {
   await axios.get('logout')
   setAuth(false) //or conditional state
}

LoginContext 子级可以访问上下文值

<LoginContextProvider>
 <Navbar />
</LoginContextProvider>

可以在导航栏或其他组件中使用 isAuth

var {isAuth} = useContext(LoginContext)