反应版本:18.3.1
重现步骤
创建一个在 a 内渲染子级的组件,但仅在它获得对该 div 的引用之后(通过将 div 节点置于某种状态) 将延迟加载的组件作为子组件传递
所以基本上是这样的:
import { Suspense, lazy, useState } from 'react';
const LazyLoadedComponent = lazy(
() =>
new Promise((resolve) => {
setTimeout(
() =>
resolve({
default: () => <div>Lazy loaded component</div>,
}),
500,
);
}),
);
const RenderAfterMount = (props) => {
const [node, setNode] = useState(null);
return <div ref={setNode}>{node && props.children}</div>;
};
export const App = () => (
<Suspense>
<RenderAfterMount>
<LazyLoadedComponent />
</RenderAfterMount>
</Suspense>
);
代码示例链接:
https://stackblitz.com/edit/vitejs-vite-uqnpwm?file=src%2FApp.jsx
当前行为
由于无限循环而导致运行时错误。
预期行为
延迟加载的组件已渲染。
您可以使用
const ref = useRef()
捕获节点的引用,但我不理解您的用例,Suspense 内部的内容被视为一个单元,因此即使一个组件需要时间,所有其他组件都会渲染一次需要时间解决的问题,总之不需要添加 RenderAfterMount 就可以正常工作了
import { Suspense, lazy, useRef, useState } from 'react';
import './styles.css';
const LazyLoadedComponent = lazy(
() =>
new Promise((resolve) => {
setTimeout(
() =>
resolve({
default: () => (
<div style={{ background: 'green' }}>Lazy loaded component</div>
),
}),
5000
);
})
);
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Suspense>
<SomeRandomComponent/>
<LazyLoadedComponent />
</Suspense>
</div>
);
}
const SomeRandomComponent = (props) => {
return <div>rendering</div>
};
在此示例中,文本渲染和实际延迟加载的组件都将在 5 秒后渲染