[英]DOM Manipulation With `useEffect()` vs. `useLayoutEffect()`
在我的应用程序组件中,我有:
function App() {
const appRef = useRef();
return (
<div
ref={appRef}
className="app position-relative overflow-hidden"
dir="rtl"
>
<NavBar cssCalsses="py-14 px-20 px-lg-0" />
<Switch>
<Route exact path="/">
<HomePage appRef={appRef} />
</Route>
<Route exact path="/tariff">
<TariffPage appRef={appRef} />
</Route>
<Route exact path="/blog">
<MagazinesPage appRef={appRef} />
</Route>
<Route exact path="/blog/:blogId">
<MagazinePage appRef={appRef} />
</Route>
<Route exact path="/free-class">
<FreeClass appRef={appRef} />
</Route>
<Route exact path="/room-log">
<RoomLog appRef={appRef} />
</Route>
<Route>
<NotFound appRef={appRef} />
</Route>
</Switch>
<MainFooter />
</div>
);
}
在每个页面组件中,我都有类似的内容:
useEffect(() => {
appRef.current.style.background =
"background value ...";
}, [appRef]);
现在,如果我将useEffect
更改为 useLayoutEffect , useLayoutEffect
收到Cannot read property 'style' of undefined
错误。
如果我像下面这样使用它,我不会有任何错误:
useLayoutEffect(() => {
document.querySelector('.app').style.background =
"background value ...";
}, [appRef]);
现在:
ref
和useEffect
操作dom
? 或者用querySelector
和useLayoutEffect
?为了解决您的第一个问题,我创建了一个代码框。
代码:-
import { useLayoutEffect, useEffect, useRef } from "react";
import "./styles.css";
export default function App() {
const appRef = useRef();
console.log("parent render start");
useLayoutEffect(() => {
console.log("parent layoutEffect", appRef.current.style);
}, [appRef]);
useEffect(() => {
console.log("parent effect", appRef.current.style);
}, [appRef]);
console.log("parent render end");
return (
<div ref={appRef} className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Child appRef={appRef} />
</div>
);
}
function Child({ appRef }) {
console.log("child render start");
useLayoutEffect(() => {
console.log("child layoutEffect", appRef.current.style);
}, [appRef]);
useEffect(() => {
console.log("child effect", appRef.current.style);
}, [appRef]);
console.log("child render end");
return <></>;
}
OUTPUT:-
parent render start
parent render end
child render start
child render end
child layoutEffect undefined
parent layoutEffect CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: ""…}
child effect CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: ""…}
parent effect CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: ""…}
从上面我们可以看出:-
孩子的useLayoutEffect
和appRef
作为依赖项在父母的useLayoutEffect
和appRef
之前运行。 在那之前appRef
仍然是undefined
的,因为React在useLayoutEffect
之前更新了 DOM。 因此,除非DOM 已更新,否则appRef
不会设置为子元素所需的DOM 元素。
另一方面,孩子的useEffect
和appRef
在父母的useLayoutEffect
和appRef
之后运行。 这就是为什么appRef
具有正确的 DOM 元素值的原因。
这是一个很好的流程图来参考这个 - https://github.com/donavon/hook-flow
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.