It is my Auth Login form. I have AuthContext. Let's try log in.
I've clicked "log in" button. And we see AuthContext "user" : underfind
Then click reload page, and here we go, we have logged in
为什么会是这样呢?
登录.js
import React, {useState} from 'react'
import {useLogin} from '../hooks/useLogin'
import { useNavigate } from 'react-router-dom'
const Login = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const {login, error, isLoading} = useLogin()
let navigate = useNavigate()
const handleSubmit = async (e) => {
e.preventDefault()
await login(email, password)
}
return(
<div className='container'>
<h1>
login page
</h1>
<form className={'d-flex flex-column'} onSubmit={handleSubmit}>
<h3>Log in</h3>
<label>Email:</label>
<input
type={'email'}
onChange={(e) => setEmail(e.target.value)}
/>
<label>Password</label>
<input
type={'password'}
onChange={(e) => setPassword(e.target.value)}
/>
<button disabled={isLoading} type={'submit'}>
Log in
</button>
{error && <div className={'error'}>
{error}
</div>}
</form>
</div>
)
}
export default Login;
use登录.js
import { useState } from "react";
import { useAuthContext } from "./useAuthContext";
export const useLogin = () => {
const [error, setError] = useState(null)
const [isLoading, setIsLoading] = useState(null)
const {dispatch} = useAuthContext()
const login = async (email, password) => {
setIsLoading(true)
setError(null)
const response = await fetch('/api/user/login', {
method:'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({email, password})
})
const json = await response.json()
if(!response.ok){
setIsLoading(false)
setError(json.error)
}
if(response.ok){
localStorage.setItem('user', JSON.stringify(json))
dispatch({type:'LOGIN', paylaod:json})
setIsLoading(false)
}
}
return {login, isLoading, error}
}
AuthContext.js
import { createContext, useReducer, useEffect } from "react";
export const AuthContext = createContext()
export const authReducer = (state, action) => {
switch(action.type){
case 'LOGIN':
return {user: action.payload}
case 'LOGOUT':
return {user:null}
default:
return state
}
}
export const AuthContextProvider = ({children}) => {
const [state, dispatch] = useReducer(authReducer, {
user:null
})
useEffect(() => {
const user = JSON.parse(localStorage.getItem('user'))
if(user){
dispatch({type:'LOGIN', payload: user})
}
}, [])
console.log('AuthContext state', state)
return(
<AuthContext.Provider value={{...state, dispatch}}>
{children}
</AuthContext.Provider>
)
}
UseAuthContext.js
import { AuthContext } from "../context/AuthContext";
import { useContext } from "react";
export const useAuthContext = () => {
const context = useContext(AuthContext)
if(!context){
throw Error('useAuthContext must be used inside an AuthContextProvider')
}
return context
}
以下是Navbar.js
import React from "react";
import { useAuthContext } from "../hooks/useAuthContext";
import { useLogout } from "../hooks/useLogout";
import { Link } from "react-router-dom";
const Nav = () => {
const {logout} = useLogout()
const {user} = useAuthContext()
const handleClick= () => {
logout()
}
return(
<div>
{user && (
<div className="bg-dark text-light align-item-center d-flex justify-content-between m-auto container-fluid p-2">
<span className="m-0 p-0 d-flex align-item-center">{user.email}</span>
<button className="btn btn-outline-danger" onClick={handleClick}>logout</button>
</div>
)}
{!user && (
<div className="d-flex justify-content-between">
<Link to='/'>
<button>HOME</button>
</Link>
<Link to='/login'>
<button>LOGIN</button>
</Link>
<Link to='/signup'>
<button>SIGNUP</button>
</Link>
</div>
)}
</div>
)
}
export default Nav
Index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { AuthContextProvider } from './context/AuthContext';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<AuthContextProvider>
<App />
</AuthContextProvider>
</React.StrictMode>
);
App.js
import {BrowserRouter, Routes, Route} from 'react-router-dom'
import Nav from './components/Nav';
import Home from './pages/home';
import Login from './pages/login';
import Signup from './pages/signup';
function App() {
return (
<div>
<BrowserRouter>
<Nav/>
<Routes>
<Route path={'/'} element={<Home/>}/>
<Route path={'/login'} element={<Login/>}/>
<Route path={'/signup'} element={<Signup/>}/>
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
我不认为这是服务器错误.