React Context for user authentication: "TypeError: setUser is not a function" when logging in with correct credentials
React Context for user authentication: "TypeError: setUser is not a function" when logging in with correct credentials
我无法弄清楚为什么会出现此错误:
TypeError: setUser 不是函数 login.js:43
登录后 login.js:39
尝试使用正确的用户凭据登录时。 setUser 显然是一个函数,因为它取自 auth.js 中的 useAuth()。我在这个登录过程中使用了 React Context、会话存储、Flask 和 sqlite。
auth.js:
import { createContext, useContext, useState } from "react";
export const AuthContext = createContext();
export const AuthProvider = function({ user, children }) {
const [currentUser, setCurrentUser] = useState(user);
const setAuth = (data) => {
sessionStorage.setItem('username', data.user.username);
sessionStorage.setItem('isAdmin', data.user.isAdmin);
setCurrentUser(data.user);
}
return (
<AuthContext.Provider value={{ currentUser, setCurrentUser: setAuth }}>
{children}
</AuthContext.Provider>
)
}
export function useAuth(user) {
return useContext(AuthContext);
}
App.js:
import { useState, useEffect } from "react";
import { BrowserRouter as Router } from "react-router-dom";
import { AuthProvider, useAuth } from './context/auth';
import "bootstrap/dist/css/bootstrap.min.css";
/* Begin Import Components */
import NavigationBar from "./components/navbar";
import Public from "./components/public-components/public";
/* End Import Components */
function App(props) {
const user = useAuth();
return (
<AuthProvider user={user}>
<Router>
<NavigationBar />
<div className="container text-center">
<Public />
</div>
</Router>
</AuthProvider>
);
}
export default App;
login.js:
import { useState } from "react";
import { Link, Redirect } from 'react-router-dom';
import { useAuth } from '../../context/auth';
import { Col, Form, Row, Button } from 'react-bootstrap';
function Login(props) {
const [loggedIn, setLoggedIn] = useState(false);
const [isError, setIsError] = useState(false);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const { setUser } = useAuth();
let referer;
if(props.location.state !== undefined) {
referer = props.location.state.referer;
} else {
referer = "/";
}
function postLogin() {
const formData = new FormData();
formData.append('email', email);
formData.append('password', password);
fetch('/login', {
method: 'post',
body: formData
}).then(res => res.json())
.then(data => {
console.log('Login response data: ', data);
if(data.wrongPassword) {
setIsError(true);
} else {
setUser({username: data.user.username, isAdmin: data.user.isAdmin});
setLoggedIn(true);
}
}).catch(err => {
console.log(err);
setIsError(true);
});;
}
if(loggedIn) {
return <Redirect to={referer} />;
}
return (
<main>
<header>
<h2>Login</h2>
</header>
<section>
<Form>
<Row className="justify-content-sm-center">
<Form.Group as={Col} sm={{ span: 6 }}>
<Form.Label htmlFor="email">Email</Form.Label>
<Form.Control
controlid="email"
type="email"
value={email}
onChange={e => {
setEmail(e.target.value);
}}
placeholder="Enter email"
autoFocus
/>
</Form.Group>
</Row>
<Row className="justify-content-sm-center">
<Form.Group as={Col} sm={{ span: 6 }}>
<Form.Label htmlFor="password">Password</Form.Label>
<Form.Control
controlid="password"
type="password"
value={password}
onChange={e => {
setPassword(e.target.value);
}}
placeholder="Enter password"
/>
</Form.Group>
</Row>
<Button onClick={postLogin} variant="success">Login</Button>
</Form>
</section>
<Link to="/register">Don't have an account?</Link>
{ isError &&<p>There was a problem logging in!</p> }
</main>
)
}
export default Login;
来自 Flask 后端的登录路径 (api.py):
@app.route("/login", methods=['POST'])
def login():
try:
email = request.form['email']
password = request.form['password']
user = db.session.query(User.username, User.password).filter_by(email=email).first()
user_role = db.session.query(UserRole.role).filter_by(username=user.username).first()
if(check_password_hash(user.password, password)):
if(user_role.role == 'Admin'):
return {'user': {'username': user.username, 'isAdmin': True}}
return {'user': {'username': user.username, 'isAdmin': False}}
else:
return {'wrongPassword':True}
except:
return 'Something went wrong...'
您将变量命名为:setCurrentUser
而非 setUser
参见:
<AuthContext.Provider value={{ currentUser, setCurrentUser: setAuth }}>
所以没有setUser
从提供商
返回
我无法弄清楚为什么会出现此错误:
TypeError: setUser 不是函数 login.js:43
登录后 login.js:39
尝试使用正确的用户凭据登录时。 setUser 显然是一个函数,因为它取自 auth.js 中的 useAuth()。我在这个登录过程中使用了 React Context、会话存储、Flask 和 sqlite。
auth.js:
import { createContext, useContext, useState } from "react";
export const AuthContext = createContext();
export const AuthProvider = function({ user, children }) {
const [currentUser, setCurrentUser] = useState(user);
const setAuth = (data) => {
sessionStorage.setItem('username', data.user.username);
sessionStorage.setItem('isAdmin', data.user.isAdmin);
setCurrentUser(data.user);
}
return (
<AuthContext.Provider value={{ currentUser, setCurrentUser: setAuth }}>
{children}
</AuthContext.Provider>
)
}
export function useAuth(user) {
return useContext(AuthContext);
}
App.js:
import { useState, useEffect } from "react";
import { BrowserRouter as Router } from "react-router-dom";
import { AuthProvider, useAuth } from './context/auth';
import "bootstrap/dist/css/bootstrap.min.css";
/* Begin Import Components */
import NavigationBar from "./components/navbar";
import Public from "./components/public-components/public";
/* End Import Components */
function App(props) {
const user = useAuth();
return (
<AuthProvider user={user}>
<Router>
<NavigationBar />
<div className="container text-center">
<Public />
</div>
</Router>
</AuthProvider>
);
}
export default App;
login.js:
import { useState } from "react";
import { Link, Redirect } from 'react-router-dom';
import { useAuth } from '../../context/auth';
import { Col, Form, Row, Button } from 'react-bootstrap';
function Login(props) {
const [loggedIn, setLoggedIn] = useState(false);
const [isError, setIsError] = useState(false);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const { setUser } = useAuth();
let referer;
if(props.location.state !== undefined) {
referer = props.location.state.referer;
} else {
referer = "/";
}
function postLogin() {
const formData = new FormData();
formData.append('email', email);
formData.append('password', password);
fetch('/login', {
method: 'post',
body: formData
}).then(res => res.json())
.then(data => {
console.log('Login response data: ', data);
if(data.wrongPassword) {
setIsError(true);
} else {
setUser({username: data.user.username, isAdmin: data.user.isAdmin});
setLoggedIn(true);
}
}).catch(err => {
console.log(err);
setIsError(true);
});;
}
if(loggedIn) {
return <Redirect to={referer} />;
}
return (
<main>
<header>
<h2>Login</h2>
</header>
<section>
<Form>
<Row className="justify-content-sm-center">
<Form.Group as={Col} sm={{ span: 6 }}>
<Form.Label htmlFor="email">Email</Form.Label>
<Form.Control
controlid="email"
type="email"
value={email}
onChange={e => {
setEmail(e.target.value);
}}
placeholder="Enter email"
autoFocus
/>
</Form.Group>
</Row>
<Row className="justify-content-sm-center">
<Form.Group as={Col} sm={{ span: 6 }}>
<Form.Label htmlFor="password">Password</Form.Label>
<Form.Control
controlid="password"
type="password"
value={password}
onChange={e => {
setPassword(e.target.value);
}}
placeholder="Enter password"
/>
</Form.Group>
</Row>
<Button onClick={postLogin} variant="success">Login</Button>
</Form>
</section>
<Link to="/register">Don't have an account?</Link>
{ isError &&<p>There was a problem logging in!</p> }
</main>
)
}
export default Login;
来自 Flask 后端的登录路径 (api.py):
@app.route("/login", methods=['POST'])
def login():
try:
email = request.form['email']
password = request.form['password']
user = db.session.query(User.username, User.password).filter_by(email=email).first()
user_role = db.session.query(UserRole.role).filter_by(username=user.username).first()
if(check_password_hash(user.password, password)):
if(user_role.role == 'Admin'):
return {'user': {'username': user.username, 'isAdmin': True}}
return {'user': {'username': user.username, 'isAdmin': False}}
else:
return {'wrongPassword':True}
except:
return 'Something went wrong...'
您将变量命名为:setCurrentUser
而非 setUser
参见:
<AuthContext.Provider value={{ currentUser, setCurrentUser: setAuth }}>
所以没有setUser
从提供商