javascript 使用中的执行顺序

zazmityj  于 2023-04-10  发布在  Java
关注(0)|答案(1)|浏览(175)

我希望当我在父组件中的输入中写入内容时,组件更新。并且我期望在useEffects中执行的顺序2组件是this =〉1.end child 2.child 3.end parent 4.parent,但结果是=〉1.end child 2.end parent 3.child 4.parent。为什么是结果?

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('parent'); //4

    return ()=>{console.log('end parent')} //3
  },[first,second])

  return (
    <>
    <h1>I am parent</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('child'); //2
     
      return ()=>{console.log('end child')} //1
      
  },[extra,force,fistargument,secondargument])

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

export default App;

>
js81xvg6

js81xvg61#

子组件的useEffect在父组件之前被调用。在代码示例中,父组件首先开始呈现,然后是子组件。子组件在父组件之前完成呈现,因此首先调用其useEffect挂钩,然后是父组件的。此行为是正常的。
是的,有一种方法可以在父级中使用useLayoutEffect在子级之前运行效果。

useLayoutEffect:useLayoutEffect同步运行,在浏览器有机会绘制之前。

与useEffect Hook类似,useLayoutEffect Hook允许您执行副作用,如API调用、设置订阅以及手动操作函数组件中的DOM。
虽然React在执行DOM更新后会触发useEffect和useLayoutEffect,但useLayoutEffect是在浏览器绘制这些更新之前同步调用的,而useEffect是在浏览器绘制这些更新之后异步调用的。
因此,在useLayoutEffect运行之前,浏览器无法绘制任何浏览器更新。因此,您将主要使用useEffect,它在副作用运行时向用户显示浏览器中的加载器。
然而,在一些情况下,我们希望在向用户显示更新之前运行副作用并更新DOM。我们可以使用以下语法使用useLayoutEffect来完成此操作。
您可以查看整个博客和一些编码示例here

相关问题