在反应虚拟化中异步加载组件?
Async loading of components in react-virtualized?
我在组件中实现了一个反应虚拟化的砖石网格,如下所示:
const MasonrySubmissionRender = (media: InputProps) => {
function cellRenderer({ index, key, parent, style }: MasonryCellProps) {
//const size = (media.submissionsWithSizes && media.submissionsWithSizes.length > index) ? media.submissionsWithSizes[index].size : undefined
//const height = size ? (columnWidth * (size.height / size.width)) : defaultHeight;
function getCard(index: number, extraProps: any) {
var Comp = media.cardElement ? media.cardElement : SubmissionCard
return <Comp submission={media.media[index]} {...media.customCardProps} />
}
return (
<div>
<CellMeasurer
cache={cache}
index={index}
key={key}
parent={parent}>
<div style={style}>
{getCard(index, media.customCardProps)}
</div>
</CellMeasurer>
</div>
);
}
return (
<Masonry
overscanByPixels={1000}
autoHeight={false}
cellCount={media.media.length}
cellMeasurerCache={cache}
cellPositioner={cellPositioner}
cellRenderer={cellRenderer}
style={{ backgroundColor: 'red' }}
height={900}
width={900}
/>
);
};
它呈现了一个相当复杂的组件列表,其中包含芯片数组、css 动画等。
由于这种渲染速度非常慢,即使使用 react-virtualized。
我想实现一个类似于 imgur.com 的系统,其中组件本身不需要立即加载,只显示一个轮廓,而我可以让组件准备在后台渲染。
我知道有一种方法可以在滚动期间换出组件,但他会隐藏所有组件,包括已经渲染的组件。
像所有反应虚拟化 cell/row 渲染器一样,masonry's cell render 被传递给 isScrolling
属性。当砌体滚动时,您可以呈现占位符而不是单元格内容:
if (isScrolling) return (
<div>placeholder</div>
);
此外,无论何时重新呈现无状态组件,您都将重新创建所有函数。这会给垃圾收集器带来额外的开销,并且还可能导致组件不必要地重新渲染。
将组件转换为 class 组件。 cellRenderer
应该是实例方法(使用 class 属性或在构造函数中绑定)。 getCard
可以是class方法,也可以从组件中提取出来,调用函数的时候传入media
。
您的代码应该是这样的(未测试):
function getCard(media: InputProps, index: number) {
var Comp = media.cardElement ? media.cardElement : SubmissionCard
return <Comp submission = {
media.media[index]
} { ...media.customCardProps }
/>
}
class MasonrySubmissionRender extends React.Component {
cellRenderer = ({
index,
key,
parent,
style,
isScrolling
}: MasonryCellProps) => {
if (isScrolling) return (
<div>placeholder</div>
);
return (
<div>
<CellMeasurer
cache={cache}
index={index}
key={key}
parent={parent}>
<div style={style}>
{getCard(media, index)}
</div>
</CellMeasurer>
</div>
);
}
render() {
return (
<Masonry
overscanByPixels={1000}
autoHeight={false}
cellCount={media.media.length}
cellMeasurerCache={cache}
cellPositioner={cellPositioner}
cellRenderer={this.cellRenderer}
style={{ backgroundColor: 'red' }}
height={900}
width={900}
/>
);
}
}
我在组件中实现了一个反应虚拟化的砖石网格,如下所示:
const MasonrySubmissionRender = (media: InputProps) => {
function cellRenderer({ index, key, parent, style }: MasonryCellProps) {
//const size = (media.submissionsWithSizes && media.submissionsWithSizes.length > index) ? media.submissionsWithSizes[index].size : undefined
//const height = size ? (columnWidth * (size.height / size.width)) : defaultHeight;
function getCard(index: number, extraProps: any) {
var Comp = media.cardElement ? media.cardElement : SubmissionCard
return <Comp submission={media.media[index]} {...media.customCardProps} />
}
return (
<div>
<CellMeasurer
cache={cache}
index={index}
key={key}
parent={parent}>
<div style={style}>
{getCard(index, media.customCardProps)}
</div>
</CellMeasurer>
</div>
);
}
return (
<Masonry
overscanByPixels={1000}
autoHeight={false}
cellCount={media.media.length}
cellMeasurerCache={cache}
cellPositioner={cellPositioner}
cellRenderer={cellRenderer}
style={{ backgroundColor: 'red' }}
height={900}
width={900}
/>
);
};
它呈现了一个相当复杂的组件列表,其中包含芯片数组、css 动画等。
由于这种渲染速度非常慢,即使使用 react-virtualized。
我想实现一个类似于 imgur.com 的系统,其中组件本身不需要立即加载,只显示一个轮廓,而我可以让组件准备在后台渲染。
我知道有一种方法可以在滚动期间换出组件,但他会隐藏所有组件,包括已经渲染的组件。
像所有反应虚拟化 cell/row 渲染器一样,masonry's cell render 被传递给 isScrolling
属性。当砌体滚动时,您可以呈现占位符而不是单元格内容:
if (isScrolling) return (
<div>placeholder</div>
);
此外,无论何时重新呈现无状态组件,您都将重新创建所有函数。这会给垃圾收集器带来额外的开销,并且还可能导致组件不必要地重新渲染。
将组件转换为 class 组件。 cellRenderer
应该是实例方法(使用 class 属性或在构造函数中绑定)。 getCard
可以是class方法,也可以从组件中提取出来,调用函数的时候传入media
。
您的代码应该是这样的(未测试):
function getCard(media: InputProps, index: number) {
var Comp = media.cardElement ? media.cardElement : SubmissionCard
return <Comp submission = {
media.media[index]
} { ...media.customCardProps }
/>
}
class MasonrySubmissionRender extends React.Component {
cellRenderer = ({
index,
key,
parent,
style,
isScrolling
}: MasonryCellProps) => {
if (isScrolling) return (
<div>placeholder</div>
);
return (
<div>
<CellMeasurer
cache={cache}
index={index}
key={key}
parent={parent}>
<div style={style}>
{getCard(media, index)}
</div>
</CellMeasurer>
</div>
);
}
render() {
return (
<Masonry
overscanByPixels={1000}
autoHeight={false}
cellCount={media.media.length}
cellMeasurerCache={cache}
cellPositioner={cellPositioner}
cellRenderer={this.cellRenderer}
style={{ backgroundColor: 'red' }}
height={900}
width={900}
/>
);
}
}