我遇到了一个无法解决的问题。我有注册、登录验证和注销。所以我注意到,如果我刷新页面,用户将不再登录。所以我找到了一种解决方案,就是使用本地存储,当然还有更多选项如何解决它,但这对我来说更容易理解。但正如我所料,我坚持了下来,因为
useEffect()
这不是我最强的一面。所以我希望你们能帮助我。当然,我在没有它的情况下尝试过,但在我的代码中出现了一些“红色”颜色(错误)。
这是我的代码:
这就是我在 App.js 中使用的。在那里,我使用
window.localStorage
创建一个变量 getItem
并将其添加到 MainContext
:
function App() {
// Use states
const [user, setUser] = useState(null);
const [message, setMessage] = useState('');
const isLoggedIn = window.localStorage.getItem('isLoggedIn')
// Main context
const states = { user, setUser, message, setMessage, isLoggedIn };
// Side effects
return (
<div className='App'>
<MainContext.Provider value={states}>
<BrowserRouter>
<Routes>
<Route path='/' element={isLoggedIn ? <HomePage /> : <LoginPage />}></Route>
{!user && <Route path='/register' element={<RegisterPage />}></Route>}
{!user && <Route path='/login' element={<LoginPage />}></Route>}
</Routes>
</BrowserRouter>
</MainContext.Provider>
</div>
);
}
export default App;
这是我在登录结束时的登录组件,单击登录按钮时我正在设置本地存储:
import React, { useContext, useRef } from 'react';
import MainContext from '../context/MainContext';
import { post } from '../helper/helper';
import { useNavigate } from 'react-router-dom';
export default function Login() {
const nav = useNavigate()
const { message, setMessage, setUser } = useContext(MainContext);
// Setting inputs references
const usernameRef = useRef();
const passwordRef = useRef();
const login = async () => {
// Setting a user for sign in, taking input values
const user = {
username: usernameRef.current.value,
password: passwordRef.current.value,
};
// Posting sign in user to database, if all fields validated (successfully signin), if failed (getting error message)
const result = await post(user, 'login');
if (!result.error) {
setMessage(result.message);
usernameRef.current.value = '';
passwordRef.current.value = '';
setUser(result.data);
} else {
setMessage(result.message);
}
window.localStorage.setItem('isLoggedIn', true)
nav('/')
};
return (
<div className='login'>
<h2>Sign In!</h2>
{message !== '' && <p className='signin__message'>{message}</p>}
<input ref={usernameRef} onClick={() => setMessage('')} type='text' placeholder='Enter Username' />
<input ref={passwordRef} onClick={() => setMessage('')} type='password' placeholder='Enter Password' />
<button onClick={login}>Sign In</button>
</div>
);
}
在工具栏(标题)组件中,我想显示用户已登录,然后我将在右上角显示他的用户名和头像图片,并在其附近显示注销按钮。如果用户未登录或注销,则该位置将显示“登录”和“注册”按钮。
{isLoggedIn && <UserTrigger />}
{!isLoggedIn && <NoUser />}
有用户注销逻辑。如果用户单击注销按钮,则
window.localStorage.removeItem
import React, { useContext } from 'react';
import { useNavigate } from 'react-router-dom';
import MainContext from '../context/MainContext';
export default function UserTrigger() {
const { user, setMessage, setUser } = useContext(MainContext);
const nav = useNavigate();
return (
<div className='toolbar__user'>
<div className='user'>
<img src={user.image} alt="" />
<h2>{user.username}</h2>
</div>
<div className='toolbar__logout'>
<button onClick={() => { setMessage(''); setUser(null); nav('/'); window.localStorage.removeItem('isLoggedIn') }}>
Logout
</button>
</div>
</div>
);
}
我想对这么多代码表示抱歉。但我想确保你能很好地理解它。感谢您的回答! <3
我在导航后使用了 window.location.reload(false) ,它刷新页面并导航到预期的网址,当您在新选项卡中测试它时它会失败,但对于单个选项卡来说它工作正常