【问题标题】:Apply auth changes that affect to session and react parent component应用影响会话的身份验证更改并响应父组件
【发布时间】:2021-12-10 09:55:11
【问题描述】:

我将尽我所能在这里解释我的问题,但这将是具有挑战性的,所以请耐心等待。

我有一个用 react + firebase 开发的 web 应用程序,带有 firebase 身份验证,登录现在只使用邮件和密码提供程序处理。我正在使用 react 路由器和 firebase 9。

当有人登录或注销时,身份验证令牌会保留在会话存储中,并且我在 App 组件(我页面上的第一层)中有一个条件,如果用户未登录,则会显示登录/注册链接in 和我的帐户链接,如果用户已登录。问题是我需要重新加载页面以查看更改,登录时您会被重定向到另一条路线,但作为一个反应应用程序,它不会重新加载整个页面。

我的 App.js

  const auth = getAuth();
  const App = () => {
  const [user, setUser] = useState();
  const [expanded, setExpanded] = React.useState(true);
  const [activeKey, setActiveKey] = React.useState('1');

  const handleLogout = () => {
    signOut(auth).then(()=> {
      setUser({});
      sessionStorage.clear();
      console.log("unset user");
    }).catch((err) => {
      console.error(err);
      alert(err.message);
    })
  };

  onAuthStateChanged(auth, (user) => {
    if (user) {
      setUser(user)
      sessionStorage.setItem("user", JSON.stringify(user))
      const uid = user.uid;
      console.log("set user")

    } else {

    }
  });

    useEffect(() => {
      const loggedInUser = sessionStorage.getItem("user");
      if (loggedInUser != null) {
        const foundUser = loggedInUser.toString();
        setUser(foundUser);
        console.log(user)
      }
    }, []);
    return (
      <div>

              <li className="nav-item">
                {
                  (sessionStorage.user ?
                    <div className="d-flex justify-content-around row">
                      <Link className="nav-link" to="/user/perfil">Mi cuenta</Link>
                    </div>
                    : <Link className="nav-link" to="/login">Iniciar sesión / Registrarse</Link>
                  )
                }

          </li>
  </div>
)

}

导出默认应用;

我的 login.js

const auth = getAuth();
console.log(auth.currentUser);
const loginWithEmailAndPassword = async (email, password) => {

setPersistence(auth, browserSessionPersistence)
    .then(() => {
        signInWithEmailAndPassword(auth, email, password)

    }).catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
        alert(error.message)
    })
}

class Login extends Component {
constructor() {
    super();
    this.state = {
        email: "",
        password: "",
        redirect: "",
    };
}
handleChangeEmail = () => {
    this.setState({ email: document.getElementById("email").value });
    console.log(this.state);
}
handleChangePassword = () => {
    this.setState({ password: document.getElementById("password").value })
}
handleRedirect = () => {
    this.setState({ redirect: "/aplicacion" });
    console.log(this.state);
}
handleClick = async () => {
    try {
        await loginWithEmailAndPassword(
            this.state.email,
            this.state.password
        );
        this.handleRedirect();
    } catch (err) {
        console.error(err);
        alert(err.message);
    }
};
render() {

    if (this.state.redirect) {
        return <Navigate to={this.state.redirect} />
    }
    return (
        <div className="d-flex justify-content-center" >
                                    <div className="col-6">
                                        <Link to='/recuperacion' className="tiny-text">He olvidado mi contraseña</Link>
                                    </div>
        </div>
    )
}

}

编辑:我目前正在为将位于 App.js 中的应用程序的另一部分开发重定向检测功能,目前它只是一个检查最后两条路由是否等于重定向的数组案例,这对我的口味来说几乎太暴力了,但这是我现在所拥有的。

【问题讨论】:

    标签: javascript reactjs firebase-authentication


    【解决方案1】:

    好的,我最终通过使用状态和钩子解决了重定向问题让我解释一下:

    我创建了一个名为 redirectState 的新状态及其设置器和导航器:

     const [redirectState, setRedirectState] = useState()
     let navigate = useNavigate()
    

    然后我只需要在身份验证状态更改时进行设置,以便应用知道何时重定向以及何时不重定向:

    onAuthStateChanged(auth, (user) => {
    if (user) {
      setUser(user)
      sessionStorage.setItem("user", JSON.stringify(user))
      const uid = user.uid;
      console.log("set user");
      console.log(uid)
      setRedirectState("redirect")
    } else {
      sessionStorage.clear();
      setRedirectState()
    }});
    

    最后我使用了反应路由器 useNavigate 挂钩来直接控制重定向:

      useEffect(() => {
    const loggedInUser = sessionStorage.getItem("user");
    console.log("checking user...")
    if (loggedInUser != undefined) {
      const foundUser = loggedInUser.toString();
      setUser(foundUser);
      console.log(user);
      navigate("/aplicacion")
    }else{
      console.log("no user")
      navigate("/")
    }}, [redirectState]);
    

    这可能看起来很粗糙,但该功能现在可以正常工作,当调用导航功能时,所有组件都会更新,这样应用程序每次都会显示正确的链接,我想修复一些错位的资源,但是将在另一个时间点,如果我找到改进它的编码方式的方法,将保持更新这篇文章。

    但现在我认为它已经解决了! :-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      • 2021-11-20
      • 1970-01-01
      相关资源
      最近更新 更多