首页 > 解决方案 > Ract useEffect Hook 在路由器初始化期间不运行

问题描述

我正在使用来自 youtube 教程之一的代码,这是我的 app.js:

export default function App() {
 
const [userData, setUserData] = useState({
  token: '',
  user: ''
})

useEffect(() => {

  (async () => {
    
    let token = localStorage.getItem("auth-token")
  
    if(token === null){
      localStorage.setItem("auth-token", "")
      token = "";
    }

    const tokenResponse = await Axios.post(
      "http://localhost:5000/authentication",
       null,
      {headers: {"x-auth-token": token}}
    )

    if(tokenResponse.data){

      try{
        
        const userResponse = await Axios.get(
          "http://localhost:5000/user",
          {headers: {"x-auth-token":token}}
        ) 

        setUserData({
          token,
          user: userResponse.data
        })

      } catch(error)
      {
        console.log(error.message)
      }
    }
  })();
 
}, [])
  
  return (
    <Router>
      <UserContext.Provider value={{userData, setUserData}}>
        <Switch>
      <PrivateRoute component={PanelComponent} path="/panel"  />
        </Switch>
      </UserContext.Provider>
    </Router>

  );
}

渲染页面后,第一次它不会运行我的useEffect,并且userData vars将为空,我怎样才能以同步的方式从use effect运行身份验证以在User Context Provider中获取我的用户数据?我使用了useLayoutEffect,但结果是一样的。

它呈现我的路由器组件,并且使用私有组件,它总是显示我有一段时间没有经过身份验证,直到它再次运行使用效果挂钩,其他路由的情况相同。

我该如何解决这个问题?

标签: reactjsreact-hooks

解决方案


您需要一个加载变量。

export default function App() {
 
const [userData, setUserData] = useState({
  token: '',
  user: ''
})
const [isLoading, setIsLoading] = useState(true); 
// serves a variable to know whether the data has beenreceived.

useEffect(() => {

  (async () => {
    
    let token = localStorage.getItem("auth-token")
  
    if(token === null){
      localStorage.setItem("auth-token", "")
      token = "";
    }

    const tokenResponse = await Axios.post(
      "http://localhost:5000/authentication",
       null,
      {headers: {"x-auth-token": token}}
    )

    if(tokenResponse.data){

      try{
        
        const userResponse = await Axios.get(
          "http://localhost:5000/user",
          {headers: {"x-auth-token":token}}
        ) 

        setUserData({
          token,
          user: userResponse.data
        })
        setIsLoading(false) // We have the data so we set loading to false

      } catch(error)
      {
        console.log(error.message)
      }
    }
  })();
 
}, [])
  if (isLoading) {
    return <div>Loading...</div>
  }
  return (
    <Router>
      <UserContext.Provider value={{userData, setUserData}}>
        <Switch>
      <PrivateRoute component={PanelComponent} path="/panel"  />
        </Switch>
      </UserContext.Provider>
    </Router>

  );
}

推荐阅读