React-window: 支持实时测量内容

创建于 2018-05-30  ·  132评论  ·  资料来源: bvaughn/react-window

为了避免增加现有列表和网格组件的成本,请创建一个新的变体(例如DynamicSizeListDynamicSizeGrid )。 此变体应在提交阶段自动测量其内容。

最有价值球员

最初的实现可能类似于CellMeasurer在react-virtualized中的工作方式:

  1. 仅当不存在当前测量值时才对内容进行测量。
  2. 如果发生变化,需要从外部(必须)重置测量。
  3. 只有在测量了该索引之前的所有单元之后,才能定位给定索引的单元。

目标

如果我们删除了上面的第三个约束,该组件可能会更好地工作,从而允许在不测量前面的项目的情况下(通过项目索引或滚动偏移量)进行随机访问。 对于诸如聊天应用程序之类的用例,这将使React-window的性能更高。

这也将释放使用ResizeObserver (通过react-measure )自动检测项目大小并完全删除位置和测量缓存的功能。 这样就不必强制性地重置缓存的测量,从而显着改善API。

为了使上述成为可能,动态列表/网格组件将需要使用截然不同的方法来将偏移量映射到索引,反之亦然。 (这个关于在react-virtualized中的“滚动锚定”的评论具有一些不错的视觉效果。)从本质上讲,我们将需要执行以下操作:

  • 根据项目数乘以estimatedItemSize道具估算总大小。 (由于下面描述的映射不是模糊的,因此无需调整此估算的大小。)

  • 滚动位置更改时,将新偏移量与上一个偏移量进行比较。 如果增量大于某个[待确定]阈值,则将新的偏移量设置为“滚动锚点”。 将偏移量映射到估计的索引(例如,将偏移量除以估计的总可滚动大小,然后将其乘以集合中的项目数)。 将此映射索引存储为“锚索引”。 例如,如果下图描述的列表包含250个项目,则“锚索引”将为132。

screen shot 2018-06-10 at 11 58 38 am

  • 滚动位置更改时,如果增量小于阈值,则选择要相对于锚点索引渲染的新项目。 相对于先前放置的项目放置这些项目。 继续上面的示例,如果列表滚动了少量(200px),则需要在先前定位的项目下方附加价值200px的其他行:

screen shot 2018-06-10 at 12 01 01 pm

上面的方法只有一个主要缺点:在列表边界正确对齐项目。 如果估计了项目索引(如上所述),则它们可能不会与可滚动区域的开始或结尾完全对齐。

  • 当用户滚动到更靠近末端时,可以通过调整总的估计大小来解决末端问题(尽管这可能会使滚动感觉有些混乱)。
  • 列表的开头较难处理,因为第一项需要与零偏移对齐,而看上去仍与偏移大于零的项连续连接。 也许可以在列表开头附近使用另一个阈值,即“安全区”(例如,如果滚动偏移量小于某个绝对值),这将强制列表测量到该点的所有单元格,以便它们正确对齐。 这种强制测量的成本将相对较低,因为它的数量很少。
    screen shot 2018-06-10 at 5 04 42 pm

使用上述方法仍无法正确处理的一种情况是设置在“安全区域”之外的滚动锚,但是当前滚动进入了安全区域内部(如下所示)。 如果用户缓慢滚动回列表的开头,则可能难以在不引入滚动混乱的情况下将第一个单元格与零对齐。
screen shot 2018-06-10 at 5 08 26 pm

👋 help wanted

最有用的评论

这个项目上没有“你们”。 由一个人维护。

在同一天对多个问题发表评论抱怨同一件事有点不体面。 无论如何,请只使用react-virtualized。

所有132条评论

有关MVP的工作正在进行中,请访问https://github.com/bvaughn/react-window/compare/master...issues/6

我在mui-downshift中使用了此方法,目前仍使用UNSAFE_componentWillReceiveProps ,尽管我计划在不久的将来尝试移植到react-window (一旦动态内容高度可用)。

这是IOS中UITableView中的可重用机制吗?

@luoboding我不明白您的问题。 您能详细说明一下吗?

@bvaughn对不起,我的朋友,我的英语不是很好。

我在我的项目中遇到问题,我在select元素中有成千上万个选项,重新加载页面时它会变得非常缓慢且卡住,我试图编写一个使它变得更好的组件,我是IOS开发人员,我知道其中的可重用机制IOS中的UITableView,如果我需要一个500px的高度选择元素,我将option-element的高度配置为100px,所以我只需要创建(Math.floor(500/100))个option元素和队列容量(当前显示的数据源队列) ),当我向上或向下滚动选择元素时,只需将其推入或弹出到队列中即可重新渲染它。

我想在我的项目中导入react-window,它能像我提到的那样工作吗?

您要描述的是反应窗口(通常是窗口和遮挡剔除)的工作方式。 但这与这个问题并没有真正的关系。 这是关于及时测量窗口内容的信息。 在您的情况下,对象具有固定的高度-因此您可以使用FixedSizeList组件: https: //react-window.now.sh/#/examples/list/fixed -size

很高兴看到在响应窗口中本地处理锚定。

顺便说一句,如果我在图表上抬高了标准,对不起...😅

@bvaughn何时发布此功能,我正在寻找

我发布了没有此功能的1.0.0,因为我现在找不到时间(精力)来完成此操作。 仍计划在将来添加它。 没有估计的时间。

看起来Polymer的“铁清单”使用的是与我在此处提议的技术类似的技术: https :

这对我们真的很有用,现在看来,我们必须使CSS与复制高度计算只是为了将其传递到虚拟列表的组件逻辑保持同步。

@kevinder您可以分享您如何处理实时测量的内容吗? 提前致谢

@carlosagsmendes不确定这是否会有所帮助,但这是我在使用此来显示聊天记录时正在做的事情:

1.)在构造函数中,为列表和ChatHistory组件创建一个引用:

  constructor(props) {
    super(props);
    this.listRef = createRef();
    this.chatHistoryRef = createRef();
    this.listHeight = 0;
  }

然后,我将引用传递给负责呈现列表的ChatHistory

2.)在父组件的componentDidMount中,我使用ChatHistory引用获取元素的高度:

componentDidMount() {
    this.listHeight = this.chatHistoryRef.current.offsetHeight;
}

3.)在父组件中,我使用聊天记录详细信息维护一个处于其状态的数组。 当向该数组添加新项时,我会这样:

  // find out how many pixels in height the text is going to use
  const size = getSize({
    text: displayText,
    className: styles.message,
  });

  let { height } = size;
  height += 20; // adds some spacing in pixels between messages
...rest of items needed for the chat history item..add them all to an array and update state

getSize基于https://github.com/schickling/calculate-size,但我对其进行了修改以支持接受类名。 该类与用作显示单个消息的容器的类相同

我敢肯定有一个更好的方法可以做到这一点,但它看起来相当快,而且我还没有遇到任何问题

@osdlge :您是否有机会在任何我可以签出的地方进行演示,例如Code Sandbox(或类似代码)?

@bvaughn可以肯定的是,我将代码的相关部分提取到了https://codesandbox.io/s/5z282z7q1l

谢谢你的分享! 😄

我已经将一些正在进行的工作推进到了对延迟测量的内容的初始处理方法,并将其扩展到名为issue / 6的分支

我还部署了一个演示:
https://react-window-next.now.sh/#/examples/list/dynamic -size

很酷。

在浏览issue / 6分支源代码和此讨论时,我仍试图通过无限滚动来理解一般性问题。 因此,下一个问题可能没有意义,但因为我真的很想进一步理解这一点,所以可以理解:

上面提到的“滚动锚点”是否与滚动锚定相关,CSS滚动锚定规范中所述的技术一样

提前致谢

它与您的第一个链接相切,但与第二个链接无关。 这只是我选择用于此问题的一个术语,因为它对我来说很有意义,而不是因为它与任何其他规范或建议有关。

我还发布了NPM的react-window的预发布版本,称为“ next”(例如yarn add react-window@next )。

您可以通过分叉以下代码沙箱来试用它:
https://codesandbox.io/s/5x8vlm0o7n

我只是测试了一下。 我尝试了10000个段落,然后尝试跳到最后。 有点儿生涩。
如果我理解正确,它应该只测量估计在末尾的行,因此它应该立即跳到末尾。 这样对吗?

2018年10月12日,12:53,Brian Vaughn [email protected]写道:

我还将NPM的react-window的预发布版本发布为“ next”(例如,yarn add react-window @ next)。

您可以通过分叉以下代码沙箱来试用它:
https://codesandbox.io/s/5x8vlm0o7n https://codesandbox.io/s/5x8vlm0o7n
-
您收到此消息是因为您已订阅此线程。
直接回复此电子邮件,在GitHub https://github.com/bvaughn/react-window/issues/6#issuecomment-429271555上查看,或使线程https://github.com/notifications/unsubscribe-auth/静音

不,我推送的初始分支未实现算法
在本期中描述。 它需要更幼稚的方法
在呈现较新的内容之前先测量较早的内容。

对困惑感到抱歉!

在2018年10月12日星期五,下午6:34 akraines [email protected]写道:

我只是测试了一下。 我尝试了10000个段落,然后尝试跳到
结尾。 有点儿生涩。
如果我理解正确,它应该只测量了估计的行
到最后,因此它应该立即跳到
结尾。 这样对吗?

2018年10月12日,12:53,Brian Vaughn [email protected]写道:

我还发布了NPM的react-window的预发布版本,
“下一个”(例如yarn add react-window @ next)。

您可以通过分叉以下代码沙箱来试用它:
https://codesandbox.io/s/5x8vlm0o7n < https://codesandbox.io/s/5x8vlm0o7n

-
您收到此消息是因为您已订阅此线程。
直接回复此电子邮件,在GitHub上查看<
https://github.com/bvaughn/react-window/issues/6#issuecomment-429271555>,
或使线程静音<
https://github.com/notifications/unsubscribe-auth/AOf2h7RmSEyGmyrEdMY6GgyZFjCKlDDFks5ukGafgaJpZM4UTb3P

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/bvaughn/react-window/issues/6#issuecomment-429282228
或使线程静音
https://github.com/notifications/unsubscribe-auth/AABznR5R1N0ErukleIfvaLQORF_NECgRks5ukHBHgaJpZM4UTb3P

嘿,
我想问一下是否有正式发布的估计?

我的团队将react-virtualized用于我们开始的新项目,但是我们需要向上滚动并跳转到特定行索引的功能(因为您可以假设我们的行具有动态内容,包含图像和其他变化的内容)。

您是否建议在其Alpha版本中迁移到react-window ? 还是我们应该等待正式发布?

另外,如果有什么办法可以帮助我完成此功能,我将很乐意为您提供帮助😄

不幸的是,由于无法进行大量测试,而且我不知道自己会遇到什么问题(或修复需要花费多长时间),因此我目前无法承诺发布时间表他们)。

如果您愿意提供帮助,一种方法是测试Alpha版本,并让我知道它的运行状况,以及是否发现任何错误。

我可能很快会更多地关注这一点,但是我无法说多久。 特别是在接下来的一两周里,我对React conf感到分心,并准备好16.6发行版。

@bvaughn很棒的工作👏终于有一些时间可以玩了。 🕹

似乎在使用display: none隐藏列表时我们需要一些调整,例如,您的页面带有两个标签,并且希望在它们之间切换而不丢失当前状态(滚动位置等),恕我直言,这不是一种罕见的用例。

简单代码沙箱提出了这个问题:
https://codesandbox.io/s/p7vq18wmjq

发生这种情况是因为,当我们不触发任何显示时,所有子代都会有offsetHeight === 0
调整大小会观察到扭结并更新新值。 如果呼叫者决定隐藏它, react-window应该不关心这种情况,基本应该通过阻止handleNewMeasurements来处理它。

如果这条线
https://github.com/bvaughn/react-window/blob/issues/6/src/DynamicSizeList.js#L443
会变成

handleNewMeasurements: instance._handleNewMeasurements

那么我们可以覆盖默认逻辑

let _handleNewMeasurements

<DynamicSizeList  
  ref={current => {
    if (current) {
      _handleNewMeasurements = current._handleNewMeasurements
      current._handleNewMeasurements = (...args) => {
        if (!isHidden) {
          return _handleNewMeasurements(...args)
        }
      }
    }
  }}
  {...otherProps}

我向该分支推送了一个更新(并向NPM发布了新的@next标记),该修复程序通过在滚动过程中使用margin-top来考虑调整大小的项目,从而解决了Firefox平滑滚动错误。 它比我想要的要复杂,但目前我不知道有更好的方法来处理此问题。 (我还需要对该方法进行更多的测试,因为我认为在极端情况下它可能还会有一些粗糙的边缘。)

我感谢上面的反馈@piecyk。 我还没有时间去研究它。 (目前,对于我来说,这仍然只是一个附带项目。)

看来我至少可以移除FirefoxscrollBy利润保证金。 不过需要先测试IE和Edge。 他们可能有自己的挑战。

是的,我知道@bvaughn ,很棒的工作👏不知道您如何找到时间! udo向您致敬!

但是让我们回到问题所在,当列表位于某个DOM元素中,而该DOM元素被隐藏而没有显示时,基本来说,我们需要检查包装器是否具有高度,宽度(如果没有),我们不想开始渲染(当前它将尝试渲染)全部清单)明天尝试修复(有藏匿物)

是的。 我了解您所描述的问题的核心。 我不喜欢通过重写/猴子修补更多实例方法来破解它的想法,因此我想首先考虑一下。

好像@next包坏了吗?

https://codesandbox.io/s/5x8vlm0o7n

不知道那是一个提出问题的合适地方,如果我错了,请原谅。 因此,简而言之:

  • 我已经将DynamicSizeListAutoResizer一起使用
  • 我被要求介绍行,其内容可以扩展(添加带有补充信息的额外div)并缩回。
  • 我还(通过redux)在这些Rows上添加了一个道具,以监听全局的展开/缩回动作。
  • 有趣的东西开始了。 我单击“扩展/收缩”,一切看起来都很棒!
  • 如果我稍微滚动然后扩展/收缩所有行,则收缩的行数与扩展的行数相同。 如果我再次展开缩回,数字将减半,依此类推。
    (即缩回30行-> 10展开->单击缩回-> 10行缩回->单击展开-> 3行展开->单击缩回-> 3行缩回)。

我尝试通过使用JSON.parse(JSON.stringify(data))hack提供一个不同但相同的对象来重新加载itemData。 没有运气 :-(

我怀疑高度的计算错误。 有解决这个问题的主意吗?

你能分享一个codesandbox的例子吗? 我需要做类似的事情,以便也许我们可以互相帮助

@vtripolitakis我刚刚找到了带有可扩展行讨论的链接

@carlosagsmendes对此表示感谢,但是我的案例研究与我使用DynamicSizeList :-(

所以我找到了问题的原因:
state.scrollOffset取负值。

src/DynamicSizeList.js我们需要在第299行添加以下代码

if (sizeDeltaForStateUpdate < 0) {
          sizeDeltaForStateUpdate = 0;
        }

嗯...乍看之下我不会指望这个修复是正确的。 大小增量可能合法地为负数,不是吗?

也许我们应该在state.scrollOffset值的更新位置周围放一个警卫( Math.max(0, prevState.scrollOffset + sizeDeltaForStateUpdate) )?

您好,当我调试我的情况时, sizeDeltaTotal取负值,并因此使sizeDeltaForStateUpdate负,在状态更新后产生负的state.scrollOffset

当我展开和缩回项目,然后滚动到具有scrollOffset 0和方向backwards的顶部时,发生了这种情况。 然后,如果我几次伸缩,就会得到负片。
是的,您的建议应该同样好。 〜现在测试。〜正常工作。

@marcneander试用版本1.4.0-alpha.1

关于在隐藏列表时忽略大小调整事件,也许像这样https://github.com/piecyk/react-window/commit/acfd88822156611cfd38872acdafbbefd2d0f78f
@bvaughn你怎么看?

我正在尝试在聊天框样式的应用程序中添加自动滚动,但遇到了以下问题: DynamicSizeList does not support scrolling to items that have not yet measured. scrollToItem() was called with index 111 but the last measured item was 110.

我正在尝试在componentDidUpdate调用scrollToItem(items.length-1) componentDidUpdate

这是预期的行为吗?

是的,也许类似的东西可以工作@ piecyk👍

这是预期的行为吗?

听起来不像@xaviergmail ,不。 也许是个错误。

@bvaughn我并不是要破坏这个问题,但我想说的是,Flex 4 DataGrid内部有一个简洁的稀疏数组实现,可以在这里提供帮助。 我知道Flash是:-1 :,但是Flex的最新版本实际上有一个非常出色的虚拟化布局引擎...因为Flash :-)

LinearLayoutVector是一个稀疏数组,用于在单个维度中的项目索引和像素位置之间进行映射。 三个基本操作是:

interface LinearLayoutVector {
   start: (index) => position;
     end: (index) => position;
  indexOf: (position) => index;
}

在内部,它以2的幂次分配存储区以存储项目位置(可以调整特定功率以更好地容纳更大或更小的项目大小)。 这样可以进行恒定时间的O(1) index -> position查找,以及对position -> index查找的有效线性块扫描。 它支持填充,间距,默认大小以及随机访问的插入,删除和更新。

大约6年前,当我为移动设备做很多虚拟化UI时,我将其移植到JS 。 它可以使用ES6的更新来提高可读性,并可能通过切换到类型化数组来提高速度,但是基本逻辑是合理的。

我提交了一份PR草案对虚拟化进行反应虚拟化,该LVR切换了CellSizeAndPositionManager的内部结构,并且确实解决了一些性能/缓存失效问题。 如果您不满意,我很乐意在接下来的几周内向react-window提交类似的PR。

@ trxcllnt👋

如果您有兴趣分享PR,我很乐意看一看。 您可能要针对issues/6分支(WIP PR#102)。

乍一看, linear-layout-vector看起来并没有经过任何测试或使用得过多,因此我最初会有一点勉强,但我仍然愿意看看。 我还想看看在被丑化和缩小之后,它增加了多少重量,但我不希望它增加太多。 😄

@bvaughn不费吹灰之力,我完全理解。 这是我几年前在圣诞节IIRC上所做的事情。 我会清理它并确保它带有完整的测试套件。 也不必担心会产生额外的依赖关系。 这么少的一堂课,我很乐意直接贡献力量。

发表评论后,我记得我有一个演示程序,是我为以下端口做的: https :

@bvaughn感谢您在过去一年的
我目前正在测试^1.6.0-alpha.1并计划将该版本运送到生产环境。

以为我会发布我需要做的事情,以便与其他DynamicSizeList一起工作,供其他查看此问题并在分支机构使用最新消息的人使用。

按照上面链接的文档以及从issue / 6分支生成的文档,将导致

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

因此解决方法是模仿您在测试中所做的工作...

import { DynamicSizeList as List } from 'react-window';
import AutoSizer from 'react-virtualized-auto-sizer';

// in constructor(props) for handling scrolling
this.listRef = React.createRef();

// in render()
const allItems = [...];
const Renderer = ({ forwardedRef, style, index, ...rest }) => (
  <div ref={forwardedRef} style={style}>
    <MyCoolComponent index={index} otherProps={otherPropsBasedOnAllItems} />
  </div>
);

const RefForwarder = React.forwardRef((props, ref) => (
  <Renderer forwardedRef={ref} {...props} />
));

return <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
  <div style={{ flexGrow: 0, flexShrink: 0, width: '100%', position: 'sticky', top: 0, zIndex: zIndexHideLayers }}>
    <MyCoolComponentThatControlsScrolling listRef={this.listRef} />
  </div>
  <div style={{ flex: 1, width: '100%' }}>
    <AutoSizer>
      {({ height, width }) => (
        <List ref={this.listRef} itemCount={allItems.length} width={width} height={height}>
          {RefForwarder}
        </List>
      )}
    </AutoSizer>
  </div>
</div>;

我的示例可能包含的内容超出了该文档页面上您想要的内容,但希望它将使您更轻松地进行文档更新

对分支的当前版本有反馈意见吗?
well效果很好
again再次感谢您所做的所有工作!

编辑: DynamicSizeList严重地使该库现在变得易于使用。

感谢您分享细节! 当我有足够的带宽来解决此问题时,我将深入研究它们。

我认为这种方法可以与本期的原始建议一起使用。

除了使用项目的先前大小,我们还可以使用估计的大小,并在有人滚动时使用实际大小进行细化。 (我认为“先前测量的尺寸”和“估计的尺寸”之间没有重要的区别,除了先前测量的尺寸可能更准确。事实上,这可能是一个可以接受的折衷方案,因为它可以我们可以跳到数据中的任意位置而无需渲染之前发生的事情,这将使我们免于维护项目大小缓存的麻烦。)

我认为这可以大大简化滚动锚定问题。 我们可以先进行初始跳转(如前所述),然后假装“之前”(上方或左侧)的所有内容都是估计的大小。 然后,当我们滚动时,进行细化。

可能行得通吗?

@bvaughn威尔此修补程序@xaviergmail解决,与最初滚动到“底部”想聊天的问题? 我创建了一个无法正常工作的示例的codesandbox。 如果没有,是否有任何解决方法?

https://codesandbox.io/s/vr648ywy3

让我们将有关此问题的评论集中在API讨论而非疑难解答上。

我建议使用Stack Overflow提出问题。

是否可以在此API中公开resetAfterIndex? 我从DynamicSizeList中添加,编辑和删除,至少从我可以收集的内容中进行添加,编辑和删除,这将是调用此方法来固定高度的方法,对吗?

@bvaughn周末在玩,想法是用锚定索引定位项目,并滚动列表以对齐用户所看到的内容……可能有效的第一印象😅为简单起见,呈现列表时没有任何过扫描元素,我们需要更改缓存的工作方式(在此wip中,它始终被清除)...您如何看待?

POC实现https://github.com/piecyk/react-window/pull/2/files
这是运行分支构建的代码沙箱
https://codesandbox.io/s/4x1q1n6nn9

嗯,当像chrome那样使用这种方法快速滚动时,firefox无法跟上渲染速度

我正在尝试在聊天框样式的应用程序中添加自动滚动,但遇到了以下问题: DynamicSizeList does not support scrolling to items that have not yet measured. scrollToItem() was called with index 111 but the last measured item was 110.

我正在尝试在componentDidUpdate调用scrollToItem(items.length-1) componentDidUpdate

这是预期的行为吗?

Kinda迟了,但我正在尝试使用react hook解决该问题。

不是最好的解决方案,但我仍在努力。 也许我们可以使它变得更通用(更简单)并创建一个包?

Gif展示它现在是如何工作的:
https://cl.ly/87ca5ac94deb

也许我们可以再开一个新的话题来讨论这种类似于聊天的行为的解决方案?

嗯,当chrome使用这种方法快速滚动时,firefox无法跟上渲染的速度

看起来它可以在Firefox Nightly 68版本中使用。

@bvaughn我正在将DynamicSizeList与InfiniteLoader和Autosizer组件一起使用,以尝试创建供稿。 我喜欢到目前为止我所看到的,继续努力:)

在API和行为方面:

  1. 我们可以像在FixedSizeList中一样,将数据对象作为itemKey回调中的第二个参数获取吗?

  2. 过滤/修改数据对象时,我们可以重置内部容器的高度吗?

我一直在使用DynamicSizeList 1.6.0-alpha.1InfiniteLoader中的

但是,现在我需要使用scrollToItem() 。 与以上评论类似,但由于尚未进行任何测量而与众不同,我得到:

DynamicSizeList does not support scrolling to items that yave not yet measured. scrollToItem() was called with index 9 but the last measured item was -1.

它似乎与时间无关,因为我尝试在较长的setTimeout之后调用它。 那么,我可以强制进行测量吗? 还是有任何解决方法?

编辑:没关系, initialScrollOffset做了我所需要的。

为什么要使用findDOMNode?

@next分支是否存在类型定义?

@WillSquire不,他们没有。 我也不确定是否可以在DefinitelyTyped的@next标签中释放它们(我可能会误解)。 另外,我认为最好等到该分支最终合并并发布新版本,因为API可能仍会更改。

@bvaughn我一直愿意在devhub上使用它,但是在我进行集成投资之前,您认为它已经处于良好状态或仍然存在一些阻塞问题?

@brunolemos我认为#102上的待办事项列表非常准确。 如果您已经测试过并且觉得它对于您所定位的浏览器来说是一个很好的状态,那么请及时通知我!

让我发布!

〜试图使用它,但到目前为止还没有成功〜

正常工作,但性能不佳。 也许我的项目渲染很昂贵或其他。

https://github.com/devhubapp/devhub/pull/152

在容器高度为100%的情况下使用AutoSizer时,最新版本似乎已损坏

编辑:我能够找到一种解决方法,使用100vh和calc()

可能有些东西坏了

太含糊,无法采取行动。 与预期行为共享一个repro?

我正在使用1.6.0-alpha.1中的DynamicSizeList,具有不同的过滤器和某些复杂的卡片视图。 但是我们需要用高度和宽度来包装。 对我来说很好。

感谢你们

您好,我正在尝试DynamicSizeList ,但是我所有的项目都呈现在彼此的顶部。 我确实将style属性传递给了呈现的项目,但是如果我登录style ,我会看到height对于每个项目, topleft是未定义的始终0
我在这里想念什么:-)?

@ graphee-gabriel您会错过一个复制示例。

最初没有故意指定高度,以使项目以其自然大小呈现。

好的,我确实了解逻辑,所以这不是项目相互渲染的原因。
我将提供尽可能多的数据,我认为可能是我犯了一个常见错误或错过了一个导致该问题的明显步骤(例如未传递样式对象)。

Screen Shot 2019-07-07 at 18 08 53

import React from 'react'
import { DynamicSizeList as List } from 'react-window'

import Layout from '../Layout'
import Text from '../Text'
import withScreenDimensions from '../withScreenDimensions'

class ListView extends React.Component {
  state = {
    availableHeight: 0
  }

  componentDidMount() {
    const checkForHeightChange = () => {
      if (this.containerDiv) {
        const { offsetHeight } = this.containerDiv
        if (this.offsetHeight !== offsetHeight) {
          this.offsetHeight = offsetHeight
          this.setState({ availableHeight: offsetHeight })
        }
      }
    }
    checkForHeightChange()
    this.intervalId = setInterval(checkForHeightChange, 10)
  }

  componentWillUnmount() {
    clearInterval(this.intervalId)
  }

  render() {
    const {
      data,
      renderItem,
      emptyText,
      dimensions,
    } = this.props
    const { width } = dimensions
    const { availableHeight } = this.state
    return (
      <Layout
        centerVertical
        style={{
          height: '100%',
        }}>
        {data && data.length > 0 ? (
          <div
            style={{
              display: 'flex',
              flex: 1,
              height: '100%',
              backgroundColor: 'red',
              alignItems: 'stretch',
              justifyContent: 'stretch',
            }}
            ref={ref => this.containerDiv = ref}
          >
            <List
              height={availableHeight}
              itemCount={data.length}
              width={width > 800 ? 800 : width}
            >
              {({ index, style }) => {
                console.log('style', style)
                return (
                  <div style={style}>
                    {renderItem({
                      item: data[index], index
                    })}
                  </div>
                )
              }}
            </List>
          </div>
        ) : (
            <Text bold center padding accent>{emptyText}</Text>
          )}
      </Layout>
    )
  }
}


export default withScreenDimensions(ListView)

分享一个“代码沙箱”,在哪里可以看到此内容?

我建议您为项目渲染器使用内联函数,而不是_not_,因为由于每次渲染父对象时它都会更改,因此会导致不必要的重新安装。 (这就是所有示例都避免使用内联函数的原因。)

@ graphee-gabriel我也有这个,文档没有提到它,但是您需要使您的行组件支持接收到引用:

Row = React.forwardRef(
      (row, ref) => (
        <div ref={ref} style={row.style}>
          {renderItem({
            item: data[row.index],
            index: row.index,
          })}
        </div>
      ),
    )

您好,您去这里:

https://codesandbox.io/s/sweet-sea-irxl8?fontsize=14

是的,对于内联函数确实是这样,这是我尝试迁移到react-window的真正老代码,并且没有花时间在这里进行改进。
感谢您的反馈意见。 让我知道您在此沙箱中找到了什么。

Annnnnd我应该在执行沙箱之前检查@brunolemos消息。
这是缺少的步骤,并修复了我的问题,谢谢!

提出了另一个问题,我更新了沙盒,以便您可以重现@bvaughn
在这里找到它: https :

现在,列表可以正常工作,但是奇怪的是,它似乎随着内容的增长而增长,并且再也没有缩小。

意义:

  1. 如果我显示6个项目,请滚动到最后,一切都很好。
  2. 更改内容以显示20个项目,滚动到最后,一切都很好。
  3. 将内容改回6个项目,滚动到最后一个项目,但是我可以继续在似乎上一个内容(20个项目数据集)还剩下的空白处滚动。

提出了另一个问题,我更新了沙盒,以便您可以重现@bvaughn
在这里找到它: https :

现在,列表可以正常工作,但是奇怪的是,它似乎随着内容的增长而增长,并且再也没有缩小。

意义:

  1. 如果我显示6个项目,请滚动到最后,一切都很好。
  2. 更改内容以显示20个项目,滚动到最后,一切都很好。
  3. 将内容改回6个项目,滚动到最后一个项目,但是我可以继续在似乎上一个内容(20个项目数据集)还剩下的空白处滚动。

我有相同的问题

这正是我所需要的。
我刚刚将1.6.0-alpha.1中的DynamicSizeList与react-virtualized-auto-sizer和react-window-infinite-loader结合使用进行了测试,结果非常好。
我有什么可以帮助实现这一目标的?

您好@bvaughn ,您是否有时间从https://github.com/bvaughn/react-window/issues/6#issuecomment -509213284检查codeandbox?

嗨,我正在为我的聊天应用程序使用DynamicSizeList。
感谢您提供的出色功能。

但是,我遇到了性能不佳和大量脚本处理的问题。
滚动时,CPU总是上升并且经常达到100%。
您对解决方案有什么想法吗?

import { useChatList } from '../../../hooks/chat/useChatList';
import LoadingSpinner from '../../../utils/LoadingSpinner';

import dynamic from 'next/dynamic';
import * as React from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
// @ts-ignore
import { DynamicSizeList as List } from 'react-window';
import { Message } from 'src/app/typings';

const { useRef, useCallback } = React;

const RowItem = React.memo(
  ({ forwardedRef, style, index, data }: any) => {
    const item = data[index] as Message;
    if (item) {
      return (
        <div id={item.messageId} ref={forwardedRef} style={style}>
          {item.text && item.text.plainText}
        </div>
      );
    }
    return null;
  },
  (prevProps, newProps) => {
    const { index, data } = prevProps;
    const { index: newIndex, data: newData } = newProps;
    let isMemo = true;
    isMemo = isMemo && index === newIndex;
    isMemo = isMemo && data.length === newData.length;
    return isMemo;
  }
);

function ChatList() {
  const listRef = useRef<HTMLInputElement>();

  const { formatMessages: messages, isLoadingMessages } = useChatList();

  const keyCreator = useCallback((index: number) => `ChatList/RowItem/${messages[index].messageId}`, [messages]);

  if (isLoadingMessages && (!messages || messages.length <= 0)) {
    return <LoadingSpinner />;
  }
  return (
    <div style={{ flex: 1, height: '100%', width: '100%' }}>
      <AutoSizer>
        {({ height, width }) => (
          <List
            ref={(lref: HTMLInputElement) => {
              if (lref !== null) {
                listRef.current = lref;
              }
            }}
            itemCount={messages.length}
            itemData={messages}
            itemKey={keyCreator}
            height={height}
            width={width}
            overscanCount={10}
          >
            {React.forwardRef((props, ref) => (
              <RowItem forwardedRef={ref} {...props} />
            ))}
          </List>
        )}
      </AutoSizer>
    </div>
  );
}

export default ChatList;

スクリーンショット 2019-07-14 11 49 54

您好@bvaughn
在调整工作场所大小时重新计算项目高度的正确方法是什么? 借助以上评论,我进行了一些演示https://codesandbox.io/s/angry-hill-tcy2m
当工作区的宽度由鼠标更改时,我需要重新计算所有项目的高度(并且可能正在清除VariableSizeList组件的内部高度缓存)...

现在有没有动态列表的任何解决方案,我只是花了4个小时试图使其正常工作,呵呵
看完所有评论后,我就完成了😠
如果你们有任何可行的解决方案,请提供给我

这个项目上没有“你们”。 由一个人维护。

在同一天对多个问题发表评论抱怨同一件事有点不体面。 无论如何,请只使用react-virtualized。

我很抱歉留下这样的布赖恩评论。 稍后我发现了这个问题,然后阅读了所有评论,我认为其他人至少会为您提供帮助

@ShivamJoker我几乎使它工作了,要使其完美工作,唯一剩下的就是总高度保持不变,但在将内容更改为更少的项目之后再也不会缩小。 如果解决了这个问题,那么在我的用例中,它似乎可以正常工作。

@bvaughn您是否有时间从https://github.com/bvaughn/react-window/issues/6#issuecomment -509213284检查沙箱中的示例?

=> https://codesandbox.io/s/sweet-sea-irxl8

它以较短的列表开头,因此:

  • 向下滚动到列表的末尾
  • 向上滚动并单击Show Long List
  • 向下滚动到最后
  • 向上滚动并单击Show Short List
  • 最后向下滚动一次,以查看简短列表,后面紧跟着许多空格。

谢谢!

@ShivamJoker我几乎使它工作了,要使其完美工作,唯一剩下的就是总高度保持不变,但在将内容更改为更少的项目之后再也不会缩小。 如果解决了这个问题,那么在我的用例中,它似乎可以正常工作。

@bvaughn您是否有时间检查#6(注释)中沙箱中的示例?

=> https://codesandbox.io/s/sweet-sea-irxl8

它以较短的列表开头,因此:

  • 向下滚动到列表的末尾
  • 向上滚动并单击Show Long List
  • 向下滚动到最后
  • 向上滚动并单击Show Short List
  • 最后向下滚动一次,以查看简短列表,后面紧跟着许多空格。

谢谢!

是的,基本上,内部容器应在数据过滤/更改时重置其高度。

@ShivamJoker我几乎使它工作了,要使其完美工作,唯一剩下的就是总高度保持不变,但在将内容更改为更少的项目之后再也不会缩小。 如果解决了这个问题,那么在我的用例中,它似乎可以正常工作。

@bvaughn您是否有时间检查#6(注释)中沙箱中的示例?

=> https://codesandbox.io/s/sweet-sea-irxl8

它以较短的列表开头,因此:

  • 向下滚动到列表的末尾
  • 向上滚动并单击Show Long List
  • 向下滚动到最后
  • 向上滚动并单击Show Short List
  • 最后向下滚动一次,以查看简短列表,后面紧跟着许多空格。

谢谢!

谢谢,我已经实现了相同的希望它也可以为其他用户正常工作
是的,我也看到滚动的高度问题

@ graphee-gabriel但我还有一个问题,我的应用程序栏过去一直向下滚动隐藏,现在没有发生,解决方案是什么?
image

再会。 我在演示项目中使用了DinamycSizeList。 一切都很好,但是过了一会儿我注意到列表组件开始无法正常工作。 起初我以为这是一些反应窗口所依赖的库。 但是看看你的演示
https://react-window-next.now.sh/#/examples/list/dynamic -size
注意到大约相同的结果,尽管在过去它也可以完美运行。 您能否建议这些错误的原因?

@simeonoff

是的,基本上,内部容器应在数据过滤/更改时重置其高度。

我应该怎么做,我试着将状态高度设置为高,但似乎没有用
有什么办法吗?

@simeonoff

是的,基本上,内部容器应在数据过滤/更改时重置其高度。

我应该怎么做,我试着将状态高度设置为高,但似乎没有用
有什么办法吗?

它必须由库在内部实现。

@ShivamJoker我几乎使它工作了,要使其完美工作,唯一剩下的就是总高度保持不变,但在将内容更改为更少的项目之后再也不会缩小。 如果解决了这个问题,那么在我的用例中,它似乎可以正常工作。

@bvaughn您是否有时间检查#6(注释)中沙箱中的示例?

=> https://codesandbox.io/s/sweet-sea-irxl8

它以较短的列表开头,因此:

  • 向下滚动到列表的末尾
  • 向上滚动并单击Show Long List
  • 向下滚动到最后
  • 向上滚动并单击Show Short List
  • 最后向下滚动一次,以查看简短列表,后面紧跟着许多空格。

谢谢!

您可以设置键以防止空格。
https://codesandbox.io/s/blissful-voice-mzjsc

您好@bvaughn谢谢您的

出于不必要的考虑,我一直在DynamicLists代码中花费大量时间,试图弄清楚如何无限制地滚动到任何地方以及如何滚动到任何项目(无论是否经过测量)。

我在这里做到了这一点https://github.com/bvaughn/react-window/compare/issues/6...Sauco82:issues / 6通过摆脱lastMeasuredIndex并使用itemIsMeasured来检查每个项目

我从未参加过开源项目,也从未使用过Flow,所以我不确定这是否有用或值得添加,也不确定是否应该直接尝试PR或在此处进行讨论。

我很乐意提供帮助和调整,因此,如果您需要任何帮助,请告诉我。

嘿,这是更简单的解决方案(无需将幽灵元素添加到DOM即可计算其大小):
密码箱

嘿,这是更简单的解决方案(无需将幽灵元素添加到DOM即可计算其大小):
密码箱

惊人的! 这个对我有用。 不错的工作。

@Kashkovsky计算的大小(如果已更新)
和itemSize调用一次

@ userbq201 @Kashkovsky很好的解决方法! 在某种情况下,它开箱即用,我不得不像下面这样修改ChatHistory.js的代码:

    const listRef = useRef(); // added
    const sizeMap = useRef({});
    const setSize = useCallback((index, size) => {
        sizeMap.current = {...sizeMap.current, [index]: size};
        listRef.current.resetAfterIndex(index); // added
    }, []);
    const getSize = useCallback(index => sizeMap.current[index] || 60, []);
    // ...
    <List ref={listRef}

否则,所有项目均以相同的默认高度渲染。 就您而言,它按原样工作,我无法解释为什么会有区别……也许@bvaughn可以。

@bvaughn如果我们必须为SSR启用类似行为该怎么办? 那边有什么提示吗?

@bvaughn是我还是您的演示无法正常工作?

不错的实现@Kashkovsky @ kirill-konshin和@ userbq201

在该解决方案中,您将如何使用备忘录?

我尝试将ChatMessage与areEqual包装在memo ,但是每次将消息添加到列表时,React仍会重新渲染每个对象。

在我的其他FixedSizedLists中,该备注可以与该memo / areEqual包装器一起正常工作,但是也许ref={root}正在影响它吗?

您可以通过粘贴一个来轻松判断React是否正在重新渲染组件

我在这里分叉了示例: https :


编辑:我修复了备忘录-它的意思是用备忘录包装初始功能组件-而不是正如我所做的。 如果有人在列表中有一个复杂的DOM结构(或者如果他们必须像我那样映射视频),这是一个建议的解决方案: https :


编辑2:事实证明,行的初始呈现是完全可以的,但是调用resetAfterIndex很难管理。 我的数据发生了变化(例如,当用户选择其他对话时)。 但是真正的问题是resetAfterIndex似乎在新的setSize可以完成之前运行。 因此,它确实成功清除了缓存的样式,但是由于浏览器尚未完成内容大小的调整,因此它只是再次生成了旧样式的新缓存。

不知道这在书面上是否有意义,但我现在必须在这上面钉上一根大头针。 请让我知道是否有人成功地动态更改了他们的内容并保持了更新的高度样式。

我还有很多其他的react-window实现,所以我真的更愿意在这里找到一个好的解决方案,而不是在这个用例中使用react-virtualized。


编辑3:这是我的最后编辑,因为我终于提出了一个半优雅的解决方案。

1.)如果itemData需要更改(即,当对话更改时),请卸载整个组件,然后使用新的itemData重新安装它。 可以使用setState回调来完成。 这样可以确保在更改数据时不保留旧的高度样式。

2.)我通过{sizeMap, setSize, listRef}传递了ChatMessage ChatContext 。 这样,我不仅可以盲目地设置大小,还可以告诉ChatMessage设置大小并将其与旧大小进行比较。 如果旧大小与新大小不同,则调用resetAfterIndexindex ,传递true强制更新。

所以我的新ChatMessage看起来像这样:

const ChatMessage = ({ message, index }) => {
    const { setSize, sizeMap, listRef } = useContext(ChatContext);
    const root = React.useRef();
    useEffect(() => {
        let oldSize = sizeMap[index];
        let newSize = root.current.getBoundingClientRect().height;
        setSize(index, newSize);
        if(newSize !== oldSize){
            listRef.current.resetAfterIndex(index,true);
        }
    }, [sizeMap, setSize, listRef]);

    return (
        <div ref={root}
             {message.body}
        </div>
    );
};
export default ChatMessage;

3.)我在其中添加了一个基本上是听众的东西等待新安装的组件被渲染。 渲染后,它将滚动到底部。 这解决了尝试将scrollTo函数直接放置在componentDidMount中的问题,因为它从未在调用该方法之前呈现。 所以看起来像这样:

class Chat extends Component {
    constructor(props) {
        super(props);
        this.listRef = createRef();
        this.state = {
            initialScrollComplete: false,
            interval: null
        };
    }

    componentDidMount(){
        // Create interval to check if list is ready. Once ready, scroll to bottom of list.
        this.setState({interval: setInterval(()=>{
            if(this.listRef.current && !this.state.initialScrollComplete){
                this.listRef.current.scrollToItem(this.props.chatHistory.length - 1, "end");
                this.setState({initialScrollComplete: true});
            }
        },25)});
    }

    componentDidUpdate(prevProps, prevState) {

        // Clear interval if scroll has been completed
        if(!prevState.initialScrollComplete && this.state.initialScrollComplete){
            clearInterval(this.state.interval);
            this.setState({interval: null});
        }

        // If new message is transmitted, scroll to bottom
        if(prevProps.chatHistory && this.props.chatHistory && prevProps.chatHistory.length !== this.props.chatHistory.length){
            this.listRef.current.scrollToItem(this.props.chatHistory.length - 1, "end");
        }

    }

    render() {
        return <ChatHistory listRef={this.listRef} chatHistory={this.props.chatHistory}/>;
    }
}

野生动物园似乎有一种很奇怪的行为。

DynamicSizedList div的高度和行的高度或边距顶部不能正常工作,内容开始重叠。

当窗口的宽度/行的内容更改时,不会重新计算或更改新的高度以适应内容的新高度。

似乎可以解决该问题的方法是:内容可滚动,滚动到不再可见该行的位置,再向上滚动使其使其正确呈现。

内容在第一页加载时无法正确呈现,因此刷新似乎无法解决问题:/

一切在其他浏览器(包括chrome和firefox)上都可以正常运行。 Safari很棒,但不幸的是,该应用仍需要使用它的人才能使用。

Screenshot 2020-02-15 at 14 27 19

我真的可以帮忙!

@tastyqbit我在Safari和Internet Explorer上也遇到了同样的问题。 如您所述,滚动经过展开的行然后向后滚动可以使其正确呈现,但是当然并不能真正解决问题。

如果您找到任何解决方法,请告诉我!

@afreix @tastyqbit我相当确定您在Safari和Internet Explorer上MDN

我认为缺少ResizeObserver应该会在控制台中生成警告。

https://codesandbox.io/s/agitated-jennings-o9nn6这样的东西怎么办?

使用#102中的VariableSizeList + ItemMeasurer进行基本操作我知道这是一种非常幼稚的方法,但是看起来它可以作为临时解决方案(不是那么糟糕😂)

在我们的团队中,我们遇到了呈现大量随机大小的文本数据的需求。
对于我们来说,必须能够准确地在项目之间跳转和滚动而不会出现任何滞后。
经过大量的在线搜索之后,我放弃了并编写了这个库
希望它对某些人来说是一个临时解决方案:smile_cat:

嘿,
我只是想更新一下,经过一些工作,我认为图书馆进入了一个不错的状态,如果您的项目在首次呈现后不改变其大小,那么它可能是一个很好的解决方案。

@ gnir-work如果窗口调整大小并且容器大小更改导致列表调整大小怎么办?

阅读此线程,我认为可能会有更好的方法来处理宽度可以更改的项目。

这里“变量”的定义在整个集合中都是可变的。 实际项目的大小是静态的,不是动态的。 也许动态是一个更好的术语,因为如果文本发生更改,则大小可能会在调整大小或更改时发生变化。

这可能的工作方式是侦听父级上的滚动。

该算法将像这样工作:

  • 计算每个商品的估计尺寸-这需要非常有效。 它不一定是完美的。 +-20%可以。

  • 我们只会渲染可见的项目+多说20%,以便用户滚动时看不到任何变化

  • 对于“高度”设置为估计高度的其他所有内容,我们都有一个“鬼”。 这只是一个空的div。 这样,滚动条就向右看。

  • 仅在视口中显示项目。 除此之外,还显示了幻影项目。

唯一的缺点是滚动条的高度将略有变化。 我不确定这是否会分散用户的注意力。 可能是滚动列表很大。 我们可以通过增加/减少缓冲区来欺骗这个问题,以使估计的大小不会影响滚动条的长度。

@ gnir-work如果窗口调整大小并且容器大小更改导致列表调整大小怎么办?

从最新版本( 2.2.0 )开始,该组件支持更改整个列表的大小(高度和宽度)。

阅读此线程,我认为可能会有更好的方法来处理宽度可以更改的项目。

这里“变量”的定义在整个集合中都是可变的。 实际项目的大小是静态的,不是动态的。 也许动态是一个更好的术语,因为如果文本发生更改,则大小可能会在调整大小或更改时发生变化。

这可能的工作方式是侦听父级上的滚动。

该算法将像这样工作:

  • 计算每个商品的估计尺寸-这需要非常有效。 它不一定是完美的。 +-20%可以。
  • 我们只会渲染可见的项目+多说20%,以便用户滚动时看不到任何变化
  • 对于“高度”设置为估计高度的其他所有内容,我们都有一个“鬼”。 这只是一个空的div。 这样,滚动条就向右看。
  • 仅在视口中显示项目。 除此之外,还显示了幻影项目。

唯一的缺点是滚动条的高度将略有变化。 我不确定这是否会分散用户的注意力。 可能是滚动列表很大。 我们可以通过增加/减少缓冲区来欺骗这个问题,以使估计的大小不会影响滚动条的长度。

这已经由@bvaughnreact-virtualized 。 这种方法的主要缺点是,跳到特定行效果不佳,并且在向上滚动时会产生视觉错误。

@ gnir-work啊..好的...也许我会中止我的工作,然后看一下反应虚拟化的。

我认为您对滚动问题是正确的,但我认为我可以通过“估计大小”来解决此问题,然后在安装组件后将其转换为实际大小。

...但是另一个问题当然是处理动态内容。 如果有更新,则组件高度会发生变化。

如果估计的大小是准确的,而不是可能的工作,例如,我前段时间实现了一个带有动态高度的虚拟化列表,并具有react-virtualized,只要估计的大小是准确的,它就可以很好地工作。 否则,滚动到行功能会破坏我的应用程序☹

从Windows 10的邮件发送

来自:凯文·伯顿(Kevin Burton)
发送:2020年4月14日,星期二23:07
至:bvaughn / react-window
抄送:尼尔·盖勒; 提到
主题:回复:[bvaughn / react-window]支持实时测量内容(#6)

@ gnir-work啊..好的...也许我会中止我的工作,然后看一下反应虚拟化的。
我认为您对滚动问题是正确的,但我认为我可以通过“估计大小”来解决此问题,然后在安装组件后将其转换为实际大小。
...但是另一个问题当然是处理动态内容。 如果有更新,则组件高度会发生变化。
-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看或取消订阅。

--
该电子邮件已被Avast防病毒软件检查过是否有病毒。
https://www.avast.com/antivirus

@ gnir-work啊...我不需要“滚动到行”功能,我想..虽然也许我错了。

满足您的需求needs

从Windows 10的邮件发送

来自:凯文·伯顿(Kevin Burton)
发送:2020年4月14日,星期二23:13
至:bvaughn / react-window
抄送:尼尔·盖勒; 提到
主题:回复:[bvaughn / react-window]支持实时测量内容(#6)

@ gnir-work啊...我不需要“滚动到行”功能,我想..虽然也许我错了。
-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看或取消订阅。

--
该电子邮件已被Avast防病毒软件检查过是否有病毒。
https://www.avast.com/antivirus

解决方法是:

  • 您的列表行高度仅取决于内部文本(可能还有一些具有确定尺寸的元素)
  • 并且列表的宽度固定

您可以使用CanvasRenderingContext2D.measureText()来计算行高,而不是渲染整个组件:poop:

CodeSandbox

@bvaughn有计划在npm上发布新的alpha版本吗? 自1.6.0-alpha.1 😕起,我们没有任何更新

@bvaughn有任何更新吗? 它会在最新版本中修复吗?

对于那些想将Typescript与DynamicSizeList -模块扩展可以为DynamicSizeList提供所需的类型,而这些类型必须使用DefinitelyTyped定义(这是我去年在此线程中发布的查询的解决方法)。

将以下内容添加到项目中:

import React, { Component } from 'react'

declare module 'react-window' {
  export type DynamicSizeListProps = Omit<FixedSizeListProps, 'itemSize' | 'scrollToItem'>
  export class DynamicSizeList extends Component<DynamicSizeListProps> {}
}

然后照常导入:

import {
  DynamicSizeList,
  DynamicSizeListProps,
} from 'react-window'

// use as normal...

@types/react-window仍然需要先对已安装的FixedSizeListProps定义。

感谢您的typedef,现在就添加它们吧! 我已经在产品中使用DynamicSizeList一年多了。 当前基于此派生: "@john-osullivan/react-window-dynamic-fork": "^1.9.0-alpha.1" (是否仍是最新的东西?)。 由于不确定是否/何时实际发布,因此我尝试切换到react-virtuoso 。 但是发现它的性能较差,因此卡住了。

@bvaughn是时候该铺上小径并将其释放给npm了吗? 如果您仍然担心它还没有准备好,也许只是将其重命名为ExperimentalDynamicSizeList

大家好! 感谢您的辛勤工作和这个出色的图书馆。 我真的很期待这个功能! 但是,我建议将有关此问题的信息添加到自述文件和文档/示例中。 我花了很长时间才弄清楚该库实际上不支持动态内容,它仅对具有固定/已知大小的项目有用。 我认为自述文件中有一个不错的常见问题解答部分,可以在其中添加。

如果您正在寻找表格/网格/树,这将是一个不错的开始https://autodesk.github.io/react-base-table/examples/dynamic-row-heights ,基于VariableSizeGrid

@ tony-scio能否请您共享一个有效的codeandbox,以将1.6.0-alpha.1中的DynamicSizeList与InfiniteLoader一起使用? 谢谢,我真的很感激。

有没有人让它可以与react-beautiful-dnd一起使用? 拖动似乎会使项目跳到彼此的顶部。

有没有人让它可以与react-beautiful-dnd一起使用? 拖动似乎会使项目跳到彼此的顶部。

我也将等待这个答案:D

[帮助]
此链接没有可显示的代码:
动态尺寸列表垂直
我需要这种能力。
谢谢

[帮助]
此链接没有可显示的代码:
动态尺寸列表垂直
我需要这种能力。
谢谢

https://react-window-next.now.sh/#/examples/list/dynamic -size

这事有进一步更新吗? 我们需要尽可能的相似的东西(通常很少,但是在某些情况下可能很多)渲染大量的响应网格项目列表(它们的高度是动态的,并且会随着各种自动换行等方式在移动设备上发生变化)。 我认为react-window如果可以处理此用例,将可以改变游戏规则。 如果没有,是否有可靠的替代方法?

这事有进一步更新吗? 我们需要尽可能的相似的东西(通常很少,但是在某些情况下可能很多)渲染大量的响应网格项目列表(它们的高度是动态的,并且会随着各种自动换行等方式在移动设备上发生变化)。 我认为react-window如果可以处理此用例,将可以改变游戏规则。 如果没有,是否有可靠的替代方法?

@JavaJamie,因为您特别要求替代方法-virtuoso库内置了用于测量动态内容的支持。 免责声明:我是它的作者。

@JavaJamie,因为您特别要求替代方法-virtuoso库内置了用于测量动态内容的支持。 免责声明:我是它的作者。

react-virtuoso的大小也是react-window的两倍。 始终必须牢记依赖项的大小。

https://bundlephobia.com/[email protected]
https://bundlephobia.com/[email protected]

我已经接受了这样的事实,即我没有时间或精力来完成这项工作。 如果有人想介入并完成我开设的分支机构,我们将竭诚欢迎您的帮助。 (有关新版本的ListGrid如何适应第二版发行,请参阅问题#302。)

为此,我们最终从零开始实施了一些措施,使得使用的可见性传感器效果非常好。

如果您想将其撕裂并创建一个新项目或将其移至此处,我可能会OSS或将您指向正确的位置。

一种技巧是我们使用“块”,以便我们可以提高性能。 基本上,我们将每一行都记录下来,然后将其实际放入约25个项目的父块中,然后在必要时将其交换。

@burtonator真的很有帮助

任何人都可以使用DynamicSizeList提供无错误的react-select实现吗?
我无法使其协同工作。
目前,我遇到2个问题(对不起,没有屏幕截图):

  1. 所有项目都具有style={position: absolute, left: 0, top: 0} ,这使我无法使用这种样式,因为所有选项都位于彼此之上。
  2. 如果我不使用样式道具,则列表会很好地显示,但是当我稍微滚动一下时,列表中带有选项的部分会缩小,而总高度保持不变。 因此,当我滚动时,得到的是实际选项的x像素,长度为x像素的空白。

找不到两者的任何有效示例。
我会注意到我在Chrome上使用1.9.0分支。

编辑。 在上方的隐藏评论部分中找到了答案。 https://github.com/bvaughn/react-window/issues/6#issuecomment -509016422

滚动问题的一种简化方法是使用滚动条来指示列表中项目的索引,而不是像素位置(如果滚动距离大约大于一个视口高度)。 组件没有尝试“向下滚动” X像素,而是仅在所需索引周围渲染项目。 中途将在索引N / 2处渲染项目,在底部将在索引N-1处渲染项目。

这将允许直接将拇指滚动到列表的中间或末端,而在组件渲染和计算尺寸时不会出现滚动拇指滞后的情况。 现在,对于很长的VariableSizeList组件,几乎不可能滚动到底部,因为光标拖动的速度快于滚动拇指的移动。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

Kizmar picture Kizmar  ·  3评论

ivan-badmaev picture ivan-badmaev  ·  3评论

maynir picture maynir  ·  4评论

bnikom picture bnikom  ·  3评论

carolin913 picture carolin913  ·  3评论