React 延迟加载 useEffect
Posted
技术标签:
【中文标题】React 延迟加载 useEffect【英文标题】:React Lazy Load useEffect 【发布时间】:2021-05-30 05:02:36 【问题描述】:我在从 useEffect 获取 clientWidth 时遇到问题。
有一个 lazyLoad 可以加载用户页面。
import Suspense, lazy from 'react';
const UsersContainer = lazy (() => import ('./ users / users-container'));
const Index = (props) =>
return (
<Suspense fallback = <div id = 'loading' />>
<UsersContainer />
</Suspense>
)
export default Index;
UsersContainer 有一个子组件 dataTooltip,如果它不适合块,它会显示完整的用户名。
import React, useEffect, useRef from 'react';
import '../common.scss';
const DataTooltip = (title, ... props) =>
let ref = useRef ();
useEffect (() =>
if (ref.current.scrollWidth> ref.current.clientWidth)
ref.current.setAttribute ('data-tooltip', title)
);
return (
<div ref = ref className = 'tooltip'>
React.cloneElement (props.children, ref: ref)
</div>
)
export default DataTooltip;
有什么问题?
UsersContainer在DOM中加载并渲染后,有'display: none',同时 DataTooltip 中的 useEffect 是异步触发的。
结果,DataTooltip 说 clientWidth = 0,因为父级有 'display: none'。
lazyLoad 移除 'display: none' 后如何让 useEffect 工作。
PS:useLayoutEffect 也一样,clientWidth = 0
这样解决了问题:
<Suspense fallback=<div id='loading'/>>
<Main/>
<Acquaintance/>
<UsersContainer/>
<RegisterContainer/>
</Suspense>
到
<Suspense fallback=<div id='loading'/>>
<Main/>
</Suspense>
<Suspense fallback=<div id='loading'/>>
<Acquaintance/>
</Suspense>
<Suspense fallback=<div id='loading'/>>
<UsersContainer/>
</Suspense>
<Suspense fallback=<div id='loading'/>>
<RegisterContainer/>
</Suspense>
【问题讨论】:
【参考方案1】:我不知道这是否能解决您的问题 - 但我立即注意到的一件事是您缺少 useEffect 挂钩中的依赖项数组。
import React, useEffect, useRef from 'react';
...
const DataTooltip = (title, ... props) =>
let ref = useRef ();
useEffect (() =>
if (ref.current.scrollWidth> ref.current.clientWidth)
ref.current.setAttribute ('data-tooltip', title)
);
return (...)
export default DataTooltip;
应该是:
import React, useEffect, useRef from 'react';
...
const DataTooltip = (title, ... props) =>
let ref = useRef ();
useEffect (() =>
if (ref.current.scrollWidth> ref.current.clientWidth)
ref.current.setAttribute ('data-tooltip', title)
, [ref]);
return (...)
export default DataTooltip;
还请记住,这将导致组件在 ref
更改时重新渲染,根据 useEffect
钩子的文档,您应该始终将 useEffect 钩子中使用的上层范围内的任何变量声明为依赖数组,如果您不使用任何此类变量,则仍应传递一个空数组以防止运行无限循环。
【讨论】:
没有帮助。我以慢速 3G 模式加载页面。延迟加载加载的用户,但设置“显示:无!重要”,此时用户得到了 useEffect,由于“显示:无!重要的'。然后延迟加载删除“显示:无”。 是的,我没想到它会解决实际问题——这只是我注意到的一个问题,无论原始问题是否得到解决,它都会导致您的代码出现问题 1. LazyLoad 使用 'display: none' 呈现页面; 2.页面触发useEffect; 3. LazyLoad 移除'display: none'。 但是你为什么要这样做呢?延迟加载内容和使用 Suspense 的目的是它不会在组件准备好之前渲染内容。看来您正在 React.Lazy/Suspense 解决方案中打包自己的延迟加载。 如果你绝对必须这样做 - 我会设置一个本地状态变量来检查你的组件的样式在你的useEffect
-hook 之前,然后将此变量作为 @987654326 的依赖项注入@,所以当它更新时,它会触发 useEffect
再次运行。您放入依赖数组中的任何变量都将导致函数在更改后再次运行。以上是关于React 延迟加载 useEffect的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法检查延迟加载的组件(使用 React.Lazy)是不是已完成加载?