首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法更改firebase身份验证signInWithEmailAndPassword中的状态

无法更改firebase身份验证signInWithEmailAndPassword中的状态
EN

Stack Overflow用户
提问于 2021-07-07 12:55:13
回答 2查看 33关注 0票数 0

我是react和firebase的新手。我正在尝试更改signInWithEmailAndPassword().then()中的isLoggedIn的值。但是我不能这样做,虽然已经调用了setIsLoggedIn(true),但它返回false

代码语言:javascript
运行
复制
import React, { useState, useContext } from 'react';
import { Link } from 'react-router-dom';
import fire from '../config/fire';
import { useHistory, useLocation } from 'react-router';
import { Context } from '../../App';

const SignIn = () => {
  const context = useContext(Context);

  // handling state of SignIn
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [emailErr, setEmailErr] = useState('');
  const [passErr, setPassErr] = useState('');
  
  // fetching the previous location
  let history = useHistory();
  let location = useLocation();
  let { previousPath } = location.state || { previousPath: { pathname: '/' } };

  const clearError = () => {
    setEmailErr('');
    setPassErr('');
  };

  const changeHistory = () => {
    if (context.isLoggedIn) {
      history.replace(previousPath);
    }
  };

  const handelSignIn = () => {
    clearError();

    fire
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then((res)=> {
        context.setIsLoggedIn(true);
        changeHistory();
      })
      .catch((err) => {
        switch (err.code) {
          case 'auth/invalid-email':
            setEmailErr('invalid e-mail, please enter a valid one.');
            break;
          case 'auth/user-not-found':
            setEmailErr('Invalid e-mail address. Please enter the valid one.');
            break;
          case 'auth/wrong-password':
            setPassErr('Invalid password.');
            break;
          default:
            setEmailErr('Something wrong. Please try again.');
            setPassErr('Something wrong. Please try again.');
        }
      });
  };

  return (
    <div>
      <Link to="/">Home</Link>

      <div
        style={{
          display: 'flex',
          height: '100vh',
          justifyContent: 'space-around',
          alignItems: 'center',
        }}
      >
        <div className="signIn">
          <input
            type="email"
            value={email}
            placeholder="E-mail"
            required
            autoFocus
            onChange={(e) => setEmail(e.target.value)}
          />
          <p>{emailErr}</p>
          <br/>

          <input
            type="password"
            value={password}
            placeholder="Password"
            required
            onChange={(e) => setPassword(e.target.value)}
          />
          <p>{passErr}</p>
          <br/>

          <button onClick={handelSignIn}>Sign In</button>
        </div>
      </div>
    </div>
  );
};

export default SignIn;
EN

回答 2

Stack Overflow用户

发布于 2021-07-07 13:15:20

更改状态是一个异步操作。到现在调用您的changeHistory时,状态实际上还没有更新。

解决这个问题的常用方法是使用useEffect钩子。但在这种情况下,将状态传递给调用可能更简单

代码语言:javascript
运行
复制
const changeHistory = (isLoggedIn) => {
  if (isLoggedIn || context.isLoggedIn) {
    history.replace(previousPath);
  }
};

context.setIsLoggedIn(true);
changeHistory(true);
票数 1
EN

Stack Overflow用户

发布于 2021-07-07 13:17:01

问题是,您调用的是在上下文中异步设置isLoggedIn状态的context.setIsLoggedIn(true)。但是,您会立即调用changeHistory()并尝试在更新context.isLoggedIn之前读取它。

如果您希望依赖于更新后的状态,请尝试使用useEffect

代码语言:javascript
运行
复制
useEffect(()=>{
  if(context.isLoggedIn) changeHistory();
 },[context])

您还可以在上下文提供程序中抽象此实现,而不是将此逻辑保留在您的组件中。在任何时候,您还可以读取当前登录用户的详细信息,或者通过在Auth对象上设置观察者来获取当前用户。这就是Firebase推荐你这样做的方式。请参阅此处的https://firebase.google.com/docs/auth/web/manage-users#get_the_currently_signed-in_user

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68280231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档