react中useEffect钩子的执行顺序是什么?

我正在用路由器创建一个简单的react应用。

我想在其中一个子组件中从服务器获取数据,但只有当用户登录时才会获取数据,所以在路由器组件中,我在useEffect hook中检查用户是否登录。

在子组件中,我向使用该变量的服务器发送请求。

但问题是子组件的useEffect运行在路由器组件的useEffect之前。

示例代码

我的路由器组件

import React, { useEffect } from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import App from "./App";
// import AllWatchers from './components/AllWatchers'

export default function Router() {
  useEffect(() => {
    console.log("router");
  }, []);
  console.log("inrouter");
  return (
    <div>
      <BrowserRouter>
        <Switch>
          <Route exact path="/" component={App} />
          {/* <Route path='/watchers' component={AllWatchers} /> */}
        </Switch>
      </BrowserRouter>
    </div>
  );
}

** 我的App(子)组件 ** 。

import React, { useEffect } from "react";
import "./styles.css";

export default function App() {
  useEffect(() => {
    console.log("App");
  }, []);
  console.log("inapp");
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

为此,输出到控制台的结果是

inrouter 
inrouter 
inapp 
inapp 
App 
router 

所以我的路由器组件是先渲染的,但App组件的useEffect钩子是先运行的,为什么?

你可以查看代码 https:/codesandbox.iosheuristic-gagarin-ego8d?file=srcApp.js:0-319。 并检查控制台

0
投票

我不知道如何解释为什么会出现这种情况,但这里有一个简单的解决方案给你。

import React, { useEffect } from "react";
import "./styles.css";

export default function App() {
  useEffect(() => {
    const timer = setTimeout(() => {
      console.log("App");
    }, 2000);
    return () => clearTimeout(timer);
  }, []);
  console.log("inapp");

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

明白了

inrouter 
inrouter 
inapp 
inapp 
router 
App 
0
投票

如果用户已经登录,你可以设置一个状态,如 const [userLoggedIn, setUserLoggedIn] = React.useState(false)

那么用户组件可以是

{userLoggedIn && <UserComponent />}

只有当用户登录时,才会呈现UserComponent。

另一种方法是,您通过 userLoggedIn 作为一个道具,然后只有当该道具为真时才会获取数据。

const UserComponent = ({userLoggedIn}) => {
  React.useEffect(() => {
    if(userLoggedIn) {
      // Function that fetchs data.
    }
  }, [userLoggedIn])
}
0
投票

根据 文件 子组件和父组件的第一次绘制是同时进行的,顺序并不重要。你最好的办法是阻止子组件的挂载,直到父组件的API调用完成加载。