我的Web应用程序具有一个可以更改高度的顶部导航栏。它固定在屏幕顶部,css位置:固定。为了将页面内容移到它下面,我有一个间隔div,它会更新其高度以匹配标题的高度,然后将其他所有内容向下推。
我正在更新我的应用程序以使用React挂钩。我有一个useLayoutEffect
钩子,该钩子检查导航栏的高度并更新间隔物的高度以匹配。根据{{3}}:
与componentDidMount或componentDidUpdate不同,使用useEffect安排的效果不会阻止浏览器更新屏幕。这使您的应用程序感觉更灵敏。大多数效果不需要同步发生。在不常见的情况下(例如,测量布局),存在一个单独的useLayoutEffect挂钩,其API与useEffect相同。
我似乎发现,React延迟加载中断useLayoutEffect
。这是一个CodeSandBox:
导航栏隐藏了一个div,其中包含文本“如果可以看到此USELAYOUTEFFECT正在工作”。使用直接导入时,该文本上方的div的大小将与导航栏匹配,将文本向下推到导航栏下方,该文本将变为可见。使用React.lazy时,useLayoutEffect
(在AppBarHeader.js中)无法正常工作。
延迟加载发生在App.js中:
//LOADING <COUNTER/> THIS WAY WORKS
// import Counter from "./Counter";
//LAZY LOADING <COUNTER/> THIS WAY BREAKS useLayoutEffect
const CounterPromise = import("./Counter");
const Counter = React.lazy(() => CounterPromise);
我想念什么?
答案 0 :(得分:1)
对于在useLayoutEffect
内某个组件被延迟加载的组件,在执行Suspense
时似乎确实是一个错误。如果AppBarHeader
是延迟加载的,而Counter
不是,则可以正常工作,但是在Counter
延迟加载的情况下,AppBarHeader
的{{1}}会在完全呈现之前执行在DOM中(高度仍为零)。
This sandbox以一种非常骇人听闻的方式“修复”,有助于进一步证明正在发生的事情。
我在useLayoutEffect
中添加了以下内容:
App.js
,然后将其传递给 replaceRefHeader = () => {
this.setState({ ref_header: React.createRef() });
};
:
Counter
然后在<Counter replaceRefHeader={this.replaceRefHeader} history={routeProps.history} />
中输入
Counter
然后将const Counter = ({ replaceRefHeader }) => {
useLayoutEffect(() => {
replaceRefHeader();
}, []);
放入[props.ref_header]
的{{1}}的依赖项数组中。
我不建议您这样做(尽管类似的方法可以作为临时解决方法)。这只是为了更清楚地说明计时问题。
我在这里记录了一个新问题:https://github.com/facebook/react/issues/14869