在 useEffect 中的执行顺序

huangapple go评论61阅读模式
英文:

Execution order in useEffect

问题

以下是代码的翻译:

我希望当我在父组件中的输入框中输入内容时组件会被更新我期望两个组件中的 useEffect 执行顺序如下 => 1. 子组件结束 2. 子组件 3. 父组件结束 4. 父组件但实际结果却是 => 1. 子组件结束 2. 父组件结束 3. 子组件 4. 父组件为什么会出现这种结果

function App() {
  
  return (
    <div className="App">
      <Container/>
      <Parent/>
    </div>
  );
}

function Parent(){
  const [first, setfirst] = useState('');
  const [second, setsecond] = useState('');
  
  function final(e){
    setsecond(e.target.value);
  }
  
  function func(e){
    setfirst(e.target.value);
  }

  useEffect(() => {
    console.log('父组件'); // 4

    return () => {
      console.log('父组件结束'); // 3
    }
  }, [first, second])

  return (
    <>
    <h1>我是父组件</h1>
    <input style={{border: "1px solid black"}} value={first} onChange={(e) => {func(e)}}/>
    <input style={{border: "1px solid black"}} value={second} onChange={(e) => {final(e)}}/>
    {
      first.length < 7 ? <Testeffect fistargument={first} secondargument={second}/> : <h1>lorem ipsum dolor</h1>
    }
    </>
  )
}

function Testeffect({ fistargument, secondargument }){
  const [extra, setextra] = useState(0);
  const [force, setforce] = useState(0);
    
  useEffect(() => {
    console.log('子组件'); // 2
     
    return () => {
      console.log('子组件结束'); // 1
    }
  }, [extra, force, fistargument, secondargument])

  return (
    <>
    <h1 onClick={() => {setextra(extra+1)}}>{fistargument}</h1>
    <h1 onClick={() => {setforce(force+1)}}>{secondargument}</h1>
    </>
  )
}

export default App;

只翻译了代码部分,没有包括问题本身。

英文:

I want when I write something in inputs that are in Parent component the component updated . and I expect order of execution in useEffects of 2 component be this => 1.end child 2.child 3.end parent 4.parent but result is => 1.end child 2.end parent 3.child 4.parent . why result is it?

function App() {
return (
&lt;div className=&quot;App&quot;&gt;
&lt;Container/&gt;
&lt;Parent/&gt;
&lt;/div&gt;
);
}
function Parent(){
const [first,setfirst] =useState(&#39;&#39;);
const [second,setsecond] =useState(&#39;&#39;);
function final(e){
setsecond(e.target.value);
}
function func(e){
setfirst(e.target.value);
}
useEffect(()=&gt;{
console.log(&#39;parent&#39;); //4
return ()=&gt;{console.log(&#39;end parent&#39;)} //3
},[first,second])
return (
&lt;&gt;
&lt;h1&gt;I am parent&lt;/h1&gt;
&lt;input style={{border:&quot;1px solid black&quot;}} value={first} onChange={(e)=&gt;{func(e)}}/&gt;
&lt;input style={{border:&quot;1px solid black&quot;}} value={second} onChange={(e)=&gt;{final(e)}}/&gt;
{
first.length &lt; 7 ? &lt;Testeffect fistargument={first} secondargument={second}/&gt; : &lt;h1&gt;lorem ipsum dolor&lt;/h1&gt;
}
&lt;/&gt;
)
}
function Testeffect({fistargument,secondargument}){
const [extra,setextra] = useState(0);
const [force,setforce] =useState(0);
useEffect(()=&gt;{
console.log(&#39;child&#39;); //2
return ()=&gt;{console.log(&#39;end child&#39;)} //1
},[extra,force,fistargument,secondargument])
return (
&lt;&gt;
&lt;h1 onClick={()=&gt;{setextra(extra+1)}}&gt;{fistargument}&lt;/h1&gt;
&lt;h1 onClick={()=&gt;{setforce(force+1)}}&gt;{secondargument}&lt;/h1&gt;
&lt;/&gt;
)
}
export default App;
&gt;

答案1

得分: 1

The child component's useEffect is being called before the parent component.
在这段代码示例中,父组件首先开始渲染,然后是子组件。子组件在父组件之前完成渲染,因此它的useEffect钩子首先被调用,然后是父组件的。这种行为是正常的。

Yes, there is a way to run effects in the parent, before the child using useLayoutEffect.
是的,可以使用useLayoutEffect在父组件中在子组件之前同步运行效果。

useLayoutEffect :
useLayoutEffect:
useLayoutEffect runs synchronously, before the browser has had a chance to paint.
useLayoutEffect在浏览器有机会绘制之前同步运行。

Like the useEffect Hook, the useLayoutEffect Hook lets you perform
side effects like API calls, setting up subscriptions, and manually
manipulating the DOM in a function component.

useEffect钩子类似,useLayoutEffect钩子允许您在函数组件中执行像API调用、设置订阅和手动操纵DOM等副作用。

Although React fires both useEffect and useLayoutEffect after
performing the DOM updates, useLayoutEffect is called before the
browser paints those updates for users to see, synchronously, while
useEffect is called after the browser paints those updates,
asynchronously.

尽管React在执行DOM更新后都会触发useEffectuseLayoutEffect,但useLayoutEffect在浏览器绘制这些更新供用户查看之前同步调用,而useEffect在浏览器绘制这些更新之后异步调用。

Therefore, the browser cannot paint any browser updates until
useLayoutEffect runs. For this reason, you’ll mostly use useEffect,
which shows your users something like a loader in the browser while
the side effects are being run.

因此,在useLayoutEffect运行之前,浏览器无法绘制任何浏览器更新。因此,大多数情况下,您会使用useEffect,这样在副作用运行时可以向用户在浏览器中显示加载程序之类的内容。

However, there are a few situations where we want to run the side
effect and update the DOM before showing our users the updates. We can
do so using useLayoutEffect with the following syntax.

但是,有一些情况下,我们希望在向用户显示更新之前运行副作用并更新DOM。我们可以使用以下语法来实现,使用useLayoutEffect

You can check the entire blog and few coding examples here
您可以在此处查看整个博客以及一些示例代码这里

英文:

The child component's useEffect is being called before the parent component.
In the code example, the parent begins rendering first, followed by the child. The child finishes rendering before the parent, and so its useEffect hook is called first, followed by the parent's. This behaviour is normal.

Yes, there is a way to run effects in the parent, before the child using useLayoutEffect.

useLayoutEffect :
useLayoutEffect runs synchronously, before the browser has had a chance to paint.

> Like the useEffect Hook, the useLayoutEffect Hook lets you perform
> side effects like API calls, setting up subscriptions, and manually
> manipulating the DOM in a function component.
>
> Although React fires both useEffect and useLayoutEffect after
> performing the DOM updates, useLayoutEffect is called before the
> browser paints those updates for users to see, synchronously, while
> useEffect is called after the browser paints those updates,
> asynchronously.
>
> Therefore, the browser cannot paint any browser updates until
> useLayoutEffect runs. For this reason, you’ll mostly use useEffect,
> which shows your users something like a loader in the browser while
> the side effects are being run.
>
> However, there are a few situations where we want to run the side
> effect and update the DOM before showing our users the updates. We can
> do so using useLayoutEffect with the following syntax.

You can check the entire blog and few coding examples here

huangapple
  • 本文由 发表于 2023年4月6日 19:39:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/75949089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定