【问题标题】:React hooks child component useEffect executes first, before parent componentReact hooks子组件useEffect首先执行,在父组件之前
【发布时间】:2021-09-27 12:00:01
【问题描述】:

我正在学习 react hooks useEffect,但我对 useEffect 的执行顺序感到困惑。在控制台中,它告诉我首先执行 ChildComponent“子组件”console.log,然后执行“挂载”useEffect,最后记录“父组件”。我期望首先记录“挂载”,然后是“父组件”,最后是“子组件”。 谁能解释为什么孩子先登录,或者为什么事情会这样执行?

Fields 是一个简单的对象数组

const fields = [
    {
        id    : 'month',
        title : 'Month'
    },
    {
        id    : 'amount',
        title : 'Amount'
    },
    {
        id    : 'year',
        title : 'Year'
    },
];

import React, { useEffect, useState } from 'react';

export default function ParentComponent(props) {
    const [fields, setFields] = useState(props.fields || []);

    useEffect(() => {
        console.log('on mount');
    }, []);

    useEffect(() => {
        console.log('parent component');
    }, [fields]);

    function randomString() {
        return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
    }



    return (
        <div>
            <button
                onClick={() => setFields([...fields,...[{id: randomString(), title: randomString()}]])}
            >Change field</button>
            <ChildComponent fields={fields}/>
        </div>
    );
}

function ChildComponent(props) {
    useEffect(() => {
        console.log('child component')
    }, [props.fields]);
    return (<div>
        {props.fields.map(({ id, title }) => <div key={id} className="field">{title}</div>)}
    </div>)
}

【问题讨论】:

  • 事件冒泡的顺序几乎相同。首先自上而下进行渲染,然后自下而上进行安装/效果执行。 useEffect 不是 setTimeout,更像是事件处理。

标签: javascript reactjs react-hooks


【解决方案1】:

它和javascript event bubbling 一样,这意味着当它运行时,它会调用所有ParentComponent 函数,这些函数将调用并渲染ChildComponent,一旦调用了inner-est 函数(子渲染)它就会冒泡再次回到顶部,现在ParentComponent's useEffect 开始并按顺序排列。

我已经修改了你的代码,所以你可以看到更多我所指的顺序 https://codesandbox.io/s/silly-jennings-9hwwv?file=/src/App.js

【讨论】:

  • 好的,我想我明白了。由于它正在安装父组件的子组件,这会导致子组件调用他们的 useEffect 函数,当它们都完成后,父组件是最后一个调用 useEffect 的?
  • 是的,useEffect 的顺序是从最内层到最外层。这也是为什么 useEffect 的参数实际上是一个函数的原因(所以 js 可以“排队”以备后用)
  • 谢谢一百万!
  • 附带问题,当状态更新时组件是否会减少?我在 useEffect 中返回的函数在状态更新后被执行。
  • 视情况而定,通常不会在 prop 更改时卸载。但是,例如,如果您返回 null,则返回 childComponent,例如。加载或交换 ChildComponent,可能会导致这种情况。随时为此提出另一个问题
猜你喜欢
  • 2021-02-06
  • 2021-02-07
  • 1970-01-01
  • 2020-08-18
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-22
相关资源
最近更新 更多