useEffect仅适用于首次更新/渲染

时间:2020-09-15 03:35:57

标签: reactjs firebase-authentication react-router-dom

我当前遇到一个问题,其中useEffect仅在第一个渲染上起作用,导致我的按钮注销不起作用,或者我对重定向做错了什么,因此该组件将永远无法到达仪表板,从而导致其无法运行useeffect吗?

以下是我目前的工作。

App.js

import React from 'react'
import './App.css'
import {
  BrowserRouter as Router,
  Switch,
  Route
} from "react-router-dom";
import UserProvider from "./providers/UserProvider"
import SignIn from "./SignIn";
import Dashboard from './Dashboard'
import PrivateRoute from './components/PrivateRoute'

function App() {

  return (
    <UserProvider>
      <Router>
        <div className="App">
          <Switch>
            <PrivateRoute path="/Dashboard" component={Dashboard}/>
            <Route path="/" component={SignIn}/>
          </Switch> 
        </div>
      </Router>
    </UserProvider>
  );
}

export default App;

Dashboard.js

import React, { useEffect, useContext, useState } from "react"
import { UserContext } from "./providers/UserProvider"
import { Redirect } from "react-router-dom"
import {logOut} from './config/firebase'

export default function Dashboard() {
    const user = useContext(UserContext);
    const [redirect, setredirect] = useState(null);
  
    useEffect(() => {
      console.log(user)
      if (!user) {
        setredirect("/"); 
      }
    }, [user]);
  
    return (!redirect) ? (
      <div>
        <h1>Welcome Home</h1>
        <button onClick={logOut}>
          <img
            src="https://img.icons8.com/ios-filled/50/000000/google-logo.png"
            alt="google icon"
          />
          <span> logout</span>
        </button>
      </div>
    ):
    (<Redirect to={redirect} />);
  }

firebase注销

export const logOut = () => {
  auth.signOut().then(()=> {
    console.log('logged out') // <-- sign out has no issue
  }).catch((error) => {
    console.log(error.message)
  })
}

发现:用户上下文已正确更新,根据我的观察,useEffect将仅在初始呈现时起作用,而不是在单击注销按钮时起作用(console.log将触发,但useEffect不会触发)

感谢有人能指出我正确的方向。谢谢。

1 个答案:

答案 0 :(得分:1)

您可以拥有一个user状态变量(用于存储用户身份验证令牌),并将其作为useEffect中的第二个参数。

通常useEffect会在每次渲染后运行,但是它也非常适合运行某些代码以响应状态变化。您可以通过将第二个参数传递给useEffect来指定效果何时运行。

将第二个参数视为“依赖项”数组–如果更改了变量,则效果应重新运行。这些可以是任何类型的变量:道具,状态或其他任何变量。

useEffect(() => {
  console.log("user state changed", user);
}, [user]);