Til*_*per 5 lazy-loading reactjs react-hooks use-effect
我在从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;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
有什么问题?
在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>
Run Code Online (Sandbox Code Playgroud)
到
<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>
Run Code Online (Sandbox Code Playgroud)
我不知道这是否可以解决您的问题 - 但我立即注意到的一件事是您缺少 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;
Run Code Online (Sandbox Code Playgroud)
应该:
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;
Run Code Online (Sandbox Code Playgroud)
另请记住,这将导致组件在发生ref更改时重新渲染,根据钩子的文档,useEffect您应该始终将 useEffect 钩子中使用的上层作用域中的任何变量声明为依赖项数组的一部分,如果您不这样做使用任何此类变量,您仍应传递一个空数组以防止运行无限循环。
| 归档时间: |
|
| 查看次数: |
8665 次 |
| 最近记录: |