问题描述
我正在尝试通过表单输入更新 UserContext,但上下文的值仍然为 null,并且不显示“注销”按钮。 setUser 不会更改用户名和密码值,它仅初始化为 null。但是如果我删除表单部分并且只保留带有上下文静态值的按钮代码,它就可以正常工作。请帮忙。
UserContext.js
import { createContext } from "react";
export const UserContext = createContext(null);
Login.js
export const login = async (a,b) => {
return {
username: a,password: b
};
};
index.js
import React,{ useContext,createRef } from 'react'
import { UserContext } from './UserContext'
import { login } from './Login'
let u = createRef();
let p = createRef();
export default function Index() {
const { user,setUser } = useContext(UserContext);
const handleSubmit=e=>{
let uid=u.current.value;
let pwd=p.current.value;
async () => {
const user = await login(uid,pwd)
setUser(user);
}
console.log(user)
}
const printValues= e =>{
let uid=u.current.value;
let pwd=p.current.value;
e.preventDefault();
console.log(uid,pwd)
}
return (
<div>
HOME!
<pre>{JSON.stringify(user,null,2)}</pre>
{user ? (
<button
onClick={() => {
// call logout
setUser(null);
}}
>
logout
</button>
) : (
<form onSubmit={handleSubmit}>
<label>
Username:
<input
ref={u}
name="username"
onChange={printValues}
/>
</label>
<br />
<label>
Password:
<input
ref={p}
name="password"
onChange={printValues}
/>
</label>
<br />
<button>Login</button>
</form>
)}
</div>
)
}
解决方法
这就是我使用上下文 API 实际处理登录的方式 - 也许这些示例可以帮助您。 另外,检查这个little tutorial - 我也在学习
import { createContext,useState,useEffect,ReactNode } from "react";
const AuthContext = createContext({});
export function AuthProvider({ children }) {
const [token,setToken] = useState(undefined);
const [user,setUser] = useState(undefined);
const [signed,setSigned] = useStatefalse);
const [loading,setLoading] = useState(true);
const [useEffectHandle,TriggerUseEffect] = useState(false);
const signIn = async (received,SignType) => {
try {
//Here is my API CALL
const RequestResponse = await api.post(
"/auth/" + SignType + "/login",received
);
const token: string = RequestResponse.data.token;
const user = JSON.stringify(RequestResponse.data.user);
setUser(RequestResponse.data.user);
setToken(token);
setSigned(true);
TriggerUseEffect(true);
sessionStorage.setItem("@odontoeasy:token",token);
sessionStorage.setItem("@odontoeasy:user",user);
} catch (error) {
if (error.response) {
// Request made and server responded
console.log({
response: {
status: error.response.status,data: error.response.data,headers: error.response.headers,},});
} else if (error.request) {
// The request was made but no response was received
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log("Error",error.message);
}
}
};
const signOut = async () => {
sessionStorage.clear();
setUser(undefined);
setSigned(false);
};
const AuthContextValues = {
loading: loading,signIn: signIn,signOut: signOut,signed: signed,token: token,user: user,};
return (
<AuthContext.Provider value={AuthContextValues}>
{children}
</AuthContext.Provider>
);
}
export default AuthContext;
还有我的登录表格:
import { SyntheticEvent,FC,useContext,useState } from "react";
import { FiUser,FiKey } from "react-icons/fi";
import { Link } from "react-router-dom";
import Input from "@material-ui/core/Input";
import { Clinic,Dentist,Employer } from "../../@types";
import AuthContext,{ ReqBody } from "../../contexts/auth";
import "./styles.css";
import { translate } from "../../locales";
import { Button,Form,LoadingIcon,Holder,RegisterLink } from "./styles";
const LoginForm = ({ type }) => {
const { signIn,loading } = useContext(AuthContext);
const [messages,setMessages] = useState("");
const [registered_id,setClinicId] = useState("");
const [dentist_id,setDentistId] = useState("");
const [employee_id,setEmployeeId] = useState("");
const [password,setPassword] = useState("");
const [access_key,setAccessKey] = useState("");
async function handleLogin(event) {
try {
event.preventDefault();
const clinicData = { registered_id,password,access_key };
const dentistData = { dentist_id,access_key };
const employeeData = { employee_id,access_key };
if (type === 0) {
signIn(clinicData,"admin");
} else if (type === 1) {
signIn(dentistData,"dentist");
} else if (type === 2) {
signIn(employeeData,"employee");
}
} catch (error) {
console.log(error);
}
}
return (
<Form onSubmit={handleLogin}>
<Holder>
<div className="input_block">
<div className="iconContainer">
<FiUser size={25} color={"#64B5F6"} />
</div>
{type === 0 && (
<Input
required
type="text"
placeholder={translate("clinicID")}
name="clinic_id"
value={registered_id}
onChange={(event) => setClinicId(event.target.value)}
/>
)}
{type === 1 && (
<Input
required
type="text"
placeholder={translate("ID")}
name="dentist_id"
value={dentist_id}
onChange={(event) => setDentistId(event.target.value)}
/>
)}
{type === 2 && (
<Input
required
type="text"
placeholder={translate("ID")}
name="employee_id"
value={employee_id}
onChange={(event) => setEmployeeId(event.target.value)}
/>
)}
</div>
<div className="input_block">
<div className="iconContainer">
<FiKey size={25} color={"#64B5F6"} />
</div>
<Input
required
title="Six or more characters"
type="password"
placeholder={translate("password")}
name="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
/>
</div>
{loading ? (
<Button>
<LoadingIcon />
</Button>
) : (
<Button type="submit">{translate("enter")}</Button>
)}
<RegisterLink>
<Link to={"/register"}>{translate("register_link")}</Link>
</RegisterLink>
</Holder>
</Form>
);
};
export default LoginForm;