import React, { useEffect } from 'react'; function MyComponent() { useEffect(() => { // 堆代码 duidaima.com // 副作用逻辑在这里 console.log('Component rendered!'); // 清理函数(可选) return () => { console.log('Component unmounted!'); }; }, []); // 空依赖数组,只在挂载时运行 return ( <div> {/* Component JSX */} </div> ); }useEffect 在组件最初完全加载后运行,然后每次组件状态发生变化时运行。
import React, { useLayoutEffect } from 'react'; function MyComponent() { useLayoutEffect(() => { // 在这里执行副作用 // 此代码在组件渲染之后但在浏览器绘制屏幕之前运行 return () => { // 清理代码在这里(可选) }; }, []); return ( // 组件的 JSX 代码 ); }useLayoutEffect 通常与 useRef hook 一起使用,如此你可以获得对可用于读取布局信息的任何 DOM 元素的引用。
6.更改会反映在浏览器屏幕上。
import React, { useRef, useLayoutEffect } from 'react'; const SmoothScrolling = () => { const containerRef = useRef(null); useLayoutEffect(() => { const container = containerRef.current; const handleScroll = () => { // 平滑滚动到容器顶部 container.scrollTo({ top: 0, behavior: 'smooth', }); }; // 当组件被挂载时滚动到顶部 handleScroll(); // 添加事件侦听器以在后续滚动时滚动到顶部 window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); }; }, []); return ( <div ref={containerRef}> {/* 你的内容 */} </div> ); };在上面的代码中,useLayoutEffect hook 用于向容器元素添加平滑滚动功能。设置事件侦听器以侦听窗口对象上的滚动事件并调用 handlescroll 函数。该函数将使用带有 { top: 0, behavior: 'smooth' } 作为参数的 scrollTo 方法将容器平滑地滚动到顶部。useLayoutEffect 将在挂载组件时执行初始滚动到顶部。添加了清理功能以在卸载组件时删除事件侦听器。
import React, { useRef, useLayoutEffect } from 'react'; const AnimatingElements = () => { const elementRef = useRef(null); useLayoutEffect(() => { const element = elementRef.current; // 在挂载时为元素的不透明度设置动画 element.style.opacity = 0; setTimeout(() => { element.style.opacity = 1; }, 1000); return () => { // 组件卸载时清理动画 element.style.opacity = 0; }; }, []); return <div ref={elementRef}>Animate me!</div>; };上面的代码块演示了如何使用 useLayoutEffect 为元素的不透明度设置动画。元素的初始不透明度设置为 0,然后使用 setTimeout 函数在 1000 毫秒的延迟后将其设置为 1。然后 useLayoutEffect 在组件挂载后应用动画。当组件被卸载时,元素的不透明度重置为 0。
import React, { useRef, useLayoutEffect } from 'react'; const AutoFocusInput = () => { const inputRef = useRef(null); useLayoutEffect(() => { inputRef.current.focus(); }, []); return <input ref={inputRef} />; };在前面的代码中,我们使用 useLayoutEffect 在组件挂载时自动聚焦到输入字段。我们继续使用 ref 访问输入元素。在 useLayoutEffect 中,我们调用输入元素上的 focus 方法来赋予它焦点。因为我们希望它只运行一次,所以我们将依赖项数组留空 ([])。注意:对于此示例,没有清理功能,因为在卸载组件时不需要撤消焦点。
|
「useEffect Hook」 | 「useLayoutEffect Hook」 |
---|---|---|
「执行顺序」 | 在渲染并应用任何更新后运行 | 在渲染之后但在浏览器绘制屏幕之前运行 |
「执行机制」 | 异步执行 | 同步执行 |
「执行时机」 | 在渲染阶段异步执行 | 在提交阶段同步执行 |
「使用场景」 | 获取数据,订阅事件,执行副作用 | 执行测量,根据布局同步修改 DOM |
「性能」 | 无阻塞,不延迟渲染,在大多数情况下针对性能进行了优化 | 可能阻塞,可能会延迟渲染,如果不小心使用,可能会导致性能问题 |
「使用注意事项」 | 对于大多数副作用和不需要立即视觉更新的效果,更可取。 | 适用于需要在浏览器绘制之前同步应用的效果 |
「服务器端渲染 (SSR)」 | 可在客户端和服务器端渲染环境中使用。 | 不建议用于服务器端渲染,因为它可能会阻塞渲染,请改用:useEffect |
使用 useLayoutEffect 的陷阱
根据 React 官方文档,这个 hook 的一个主要缺陷是它会损害应用程序的性能。不支持服务器端渲染 (SSR):由于 SSR 需要异步呈现以避免阻塞服务器线程,因此在 SSR 设置中使用 useLayoutEffect 可能会导致服务器渲染的内容和客户端渲染的内容不匹配。
9.注意依赖关系:就像 useEffect 一样,useLayoutEffect 钩子也接受一个依赖关系数组作为第二个参数。因此,请确保包含所有相关依赖项以避免不必要的重新渲染。