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

时间:2020-04-24 23:57:56

标签: javascript reactjs react-router use-effect

我正在使用路由器创建一个简单的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>
  );
}

**我的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.io/s/heuristic-gagarin-ego8d?file=/src/App.js:0-319 并检查控制台

3 个答案:

答案 0 :(得分: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 

答案 1 :(得分:0)

如果用户已登录,则可以设置类似@php if({{$image->id}} = "6"){ echo "ID is six"; } @endphp

的状态

那么用户组件可能是

const [userLoggedIn, setUserLoggedIn] = React.useState(false)

这只会在userLoggedIn时呈现UserComponent。

另一种方法是将{userLoggedIn && <UserComponent />} 作为道具传递,然后仅在该道具为true时才获取数据。

userLoggedIn

答案 2 :(得分:0)

根据docs,孩子和父母的第一次绘画是同时发生的,顺序无关紧要。最好的选择是阻止子组件的安装,直到父组件的API调用完成加载为止。