表单值未在上下文 api React 中更新

问题描述

我正在尝试通过表单输入更新 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;