繁体   English   中英

useEffect hook 在 react 中的执行顺序是什么?

[英]What is the order for execution of useEffect hook in react?

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

我想在其中一个子组件中从服务器获取数据,但只有在用户登录时才会获取数据,因此在路由器组件中,我在 useEffect 挂钩中检查用户是否已登录。 如果它已登录,我会设置一个变量,我可以在后面访问它。

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

但问题是子组件的 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>
  );
}

** 我的应用程序(子)组件 **

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>
  );
}

为此控制台的 output 是

inrouter 
inrouter 
inapp 
inapp 
App 
router 

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

您可以查看代码https://codesandbox.io/s/heuristic-gagarin-ego8d?file=/src/App.js:0-319并检查控制台

我不知道如何解释为什么会这样,但这里有一个简短的解决方案。

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 

如果用户已登录,您可以设置 state,如const [userLoggedIn, setUserLoggedIn] = React.useState(false)

然后用户组件可以是

{userLoggedIn && <UserComponent />}

这只会在 userLoggedIn 时呈现 UserComponent。

另一种方法是将userLoggedIn作为道具传递,然后仅在该道具为真时才获取数据。

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

根据文档,首先为孩子和父母绘画同时发生,顺序无关紧要。 最好的办法是阻止子组件的安装,直到父组件的 API 调用完成加载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM