英文:
using useeffect with react router execute out of order
问题
The useEffect代码 in my route runs before my useEffect code in app.js because useEffect in React runs after the initial render of a component. In your case, the Home component (defined in Home.js) is rendered inside the RouterProvider in App.js, and its useEffect is called during that render.
This behavior is expected in React and is not something you need to prevent, as it follows the order of component rendering. If you want specific code in App.js's useEffect to run before code in Home.js's useEffect, you can place it outside the useEffect in App.js.
If you have specific synchronization or dependency requirements between these useEffect calls, you can handle them by passing dependencies or using Redux actions and reducers to manage the state in a more controlled manner.
英文:
I was trying to use useEffect in my app.js and setting some data to my redux and using that data in my route page(inside useEffect) resulting me finding this strange behavior unless it is how should be and i am in the wrong D:.
This is a simplified code to show my problem.
In the Code, I have four console.log() and the order in the browser developer console is as follows:
App.js :7 App
Home.js :4 Home
Home.js :6 homeUseEffect
App.js :9 appUseEffect
the log outside of useEffect runs as normal but inside useEffect the route runs before the app.js which the route is declared in.
app.js
import React, { useEffect } from 'react';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Home from './pages/Home';
const router = createBrowserRouter([{ path: '/', element: <Home /> }]);
const App = () => {
console.log('App');
useEffect(() => {
console.log('appUseEffect');
}, []);
return <RouterProvider router={router}></RouterProvider>;
};
export default App;
home.js
import React, { useEffect } from 'react';
const Home = () => {
console.log('Home');
useEffect(() => {
console.log('homeUseEffect');
}, []);
return <div>Home</div>;
};
export default Home;
why the useEffect code in my route runs before my useEffect code in app.js
is it how it should be?
and how can I prevent that?
答案1
得分: 2
这个行为按预期工作。
/**
* ------------------ 组合组件的生命周期 ------------------
*
* - constructor: 初始化状态。实例现在被保留。
* - componentWillMount
* - render
* - [子组件的构造函数]
* - [子组件的componentWillMount和render]
* - [子组件的componentDidMount]
* - componentDidMount
*
* 更新阶段:
* - componentWillReceiveProps(只有在父组件更新时才调用)
* - shouldComponentUpdate
* - componentWillUpdate
* - render
* - [子组件的构造函数或接收props阶段]
* - componentDidUpdate
*
* - componentWillUnmount
* - [子组件被销毁]
* - (已销毁): 实例现在为空,由React释放并准备垃圾回收。
*
* -------------------------------------------------------
*/
从 componentDidMount 文档中:
子组件的
componentDidMount()
方法在父组件之前调用。
我们还知道 useEffect(() => [])
等同于 componentDidMount()
生命周期方法。
在类组件中定义
componentDidMount
、componentDidUpdate
和componentWillUnmount
在功能上等同于在函数组件中调用useEffect
。
这就是为什么你会得到以下日志:
App
Home
homeUseEffect
appUseEffect
函数组件执行发生在 "渲染阶段",由 useEffect()
钩子或 componentDidMount()
方法声明的效果将在 "提交阶段" 执行。
请参考下面的图表:
英文:
This behavior works as expected.
/**
* ------------------ The Life-Cycle of a Composite Component ------------------
*
* - constructor: Initialization of state. The instance is now retained.
* - componentWillMount
* - render
* - [children's constructors]
* - [children's componentWillMount and render]
* - [children's componentDidMount]
* - componentDidMount
*
* Update Phases:
* - componentWillReceiveProps (only called if parent updated)
* - shouldComponentUpdate
* - componentWillUpdate
* - render
* - [children's constructors or receive props phases]
* - componentDidUpdate
*
* - componentWillUnmount
* - [children's componentWillUnmount]
* - [children destroyed]
* - (destroyed): The instance is now blank, released by React and ready for GC.
*
* -----------------------------------------------------------------------------
*/
From componentDidMount doc:
> The componentDidMount()
method of child components is invoked before that of parent components.
We also know useEffect(() => [])
is equivalent to componentDidMount()
lifecycle method.
> defining componentDidMount
, componentDidUpdate
, and componentWillUnmount
together in class components is equivalent to calling useEffect
in function components
That's why you get the logs:
App
Home
homeUseEffect
appUseEffect
The function component execution happens in the "render phrase", the effect declared by the useEffect()
hook or componentDidMount()
method will be executed in the "commit phrase".
See the below diagram:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论