useEffect和useLayoutEffect有什么区别?
Posted 前端e站
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了useEffect和useLayoutEffect有什么区别?相关的知识,希望对你有一定的参考价值。
上一节我们介绍了useRef 保存引用值和useImperativeHandle 透传 Ref,这一节之后整个React hooks的学习就告一段落了。
useLayoutEffect 同步执行副作用
大部分情况下,使用 useEffect 就可以帮我们处理组件的副作用,但是如果想要同步调用一些副作用,比如对 DOM 的操作,就需要使用 useLayoutEffect,useLayoutEffect 中的副作用会在 DOM 更新之后同步执行。
function App()
const [width, setWidth] = useState(0);
useLayoutEffect(() =>
const title = document.querySelector("#title");
const titleWidth = title.getBoundingClientRect().width;
console.log("useLayoutEffect");
if (width !== titleWidth)
setWidth(titleWidth);
);
useEffect(() =>
console.log("useEffect");
);
return (
<div>
<h1 id="title">hello</h1>
<h2>width</h2>
</div>
);
在上面的例子中,useLayoutEffect 会在 render,DOM 更新之后同步触发函数,会优于 useEffect 异步触发函数。
useEffect和useLayoutEffect有什么区别?
简单来说就是调用时机不同,useLayoutEffect和原来componentDidMount&componentDidUpdate一致,在react完成DOM更新后马上同步调用的代码,会阻塞页面渲染。而useEffect是会在整个页面渲染完才会调用的代码。
官方建议优先使用useEffect
在实际使用时如果想避免页面抖动(在useEffect里修改DOM很有可能出现)的话,可以把需要操作DOM的代码放在useLayoutEffect里。关于使用useEffect导致页面抖动,参考git仓库git仓库示例。
不过useLayoutEffect在服务端渲染时会出现一个warning,要消除的话得用useEffect代替或者推迟渲染时机。
React Hooks 不足
尽管我们通过上面的例子看到 React Hooks 的强大之处,似乎类组件完全都可以使用 React Hooks 重写。但是当下 v16.8 的版本中,还无法实现 getSnapshotBeforeUpdate 和 componentDidCatch 这两个在类组件中的生命周期函数。官方也计划在不久的将来在 React Hooks 进行实现。
父组件
import Child from 'component/Child'
const dataobj =
pdata1: 1,
pdate2:2
const [dataobj ,setDataobj ] = useState();
const pchildref = useRef();
function parantHandler()
// 子组件调用的父组件方法
function parentDivClick()
// 父组件调用子组件方法
pchildref .current._childFn();
return (
<div>
<Child
ref=pchildref
params1=dataobj.pdata1
params2=dataobj.pdata2
handlerClick=parantHandler>
</Child>
<div onClick=parentDivClick></div>
</div>
)
子组件
const Child = (props,ref) =>
// 接收父组件的传值
const params1,params2,handlerClick = props;
const childRef = useRef();
// 暴露的子组件方法,给父组件调用
useImperativeHandle(ref,() =>
return
_childFn()
// something….
)
// handlerClick子组件调用父组件方法
return <div
ref=childRef onClick=handlerClick>
</div>
// forwardRef 配合useRef 父组件调用子组件方法使用
export default forwardRef(Child);
关注我,一起学习更多的前端技术。
以上是关于useEffect和useLayoutEffect有什么区别?的主要内容,如果未能解决你的问题,请参考以下文章