React-window: 版本2的变更

创建于 2019-07-29  ·  44评论  ·  资料来源: bvaughn/react-window

这是一个总括性问题,可以与我分享即将推出的react-window版本2.0的计划。

反馈是值得

我希望从版本1升级到版本2可能需要进行实质性的代码更改,其中许多将无法使用代码模块自动进行。 因此,尤其是对于应用程序代码,除非您有充分的理由(例如,您需要支持动态大小内容),否则我建议不要升级现有代码。

我还将继续将当前文档固定到domain react-window-v1.now.sh域,以便在更新版本2时不会丢失它们。


目录:
  • 支持更少的组件
  • 使用渲染道具API
  • 不再支持水平列表
  • 仅网格支持RTL
  • 更改onScroll回调时间

    *其他更改/弃用

更少的组件

帮助管理复杂性的一种方法是减少库支持的组件数量。 我目前计划在版本2中仅支持以下组件类型:

  • SimpleList (以前是FixedSizeList

    • 当行高固定(并且提前知道)时,应使用此高度优化的列表组件。

  • List (以前是DynamicSizeList

    • 此列表应用于动态调整大小的内容(例如,聊天,新闻源)。 它需要ResizeObserver API(或polyfill)。

  • Grid (以前是VariableSizeGrid

    • 此组件应用于应沿垂直轴和水平轴虚拟化的表格数据(例如电子表格)。 它支持可变大小的行和列,但不支持自动测量和更新其大小。


渲染道具

react-virtualizedreact-window的主要变化之一是决定将children视为React元素(例如React.createElement(children, props)) )而不是渲染道具(例如children(props) )。

这样做有两个动机:

  • React提供了用于记忆的内置解决方案(例如React.memouseMemoshouldComponentUpdate ),因此我不需要为项目渲染器实现自己的缓存抽象。
  • 诸如挂钩和悬念之类的API在项目渲染器内部“正常工作”。
  • 可以通过react-window管理键,而无需渲染道具传递它们(也不需要cloneElement调用)。

不幸的是也有一些缺点:

  • 内联项目渲染器会产生高昂的成本。 由于每次父组件渲染时都会重新创建其“类型”(函数定义),因此React会深度卸载并重新渲染其渲染的树。 这意味着文档需要教人们不要使用它们,即使它们通常更方便。
  • 由于无法使用内联函数来关闭本地范围,因此项目渲染器与父项共享状态更加复杂,需要使用诸如itemData和自定义areEqual类的API进行比较

考虑到上述优点和缺点后,我决定也以react-window转换为render props方法。 这意味着,复杂的例子这样可以重新编写更容易:

const Example = ({ height, items, toggleItemActive, width }) => (
  <List
    height={height}
    itemCount={items.length}
    itemRenderer={({ index, key, style }) => {
      const item = items[index];
      return (
        <div key={key} onClick={() => toggleItemActive(index)} style={style}>
          {item.label} is {item.isActive ? "active" : "inactive"}
        </div>
      );
    }}
    itemSize={35}
    width={width}
  />
);

不再支持水平列表

以前,列表组件同时支持水平和垂直布局模式。 为了简化实现和维护,并且由于绝大多数情况是垂直列表,我将删除对layout="horizontal"


RTL支持

网格组件将继续支持direction="RTL" ,但列表将不支持(因为它们仅支持垂直布局)。 进行此折衷是为了使列表更小且更易于维护。


onItemsRenderedonScroll回调更改

列表和网格组件当前支持onItemsRenderedonScroll回调道具。 这些回调在提交阶段(列表或网格完成渲染之后)被调用。 这很有用,因为响应这些回调始终可以安全地执行副作用(例如分析日志记录),但是它也有一个缺点:任何滚动同步更新都必须在第二个渲染(级联)中完成。

版本2将对onScroll回调进行更改以解决此问题。 onScroll回调将在事件的分发周期中调用,以便任何更新都将使用列表或网格自身的更新进行批处理(由React进行)。

onItemsRendered回调将被onItemsDisplayed prop代替,尽管在提交周期中它将继续被调用。 进行此更改是为了使list组件能够通过以空闲优先级进行预渲染并利用诸如显示锁定之类的实验性API来更积极地优化渲染性能。


其他道具变更/弃用

有几个待处理的弃用(带有DEV警告)将被删除:

  • innerTagNameouterTagName用于所有列表和网格组件。 (改为使用innerElementTypeouterElementType 。)
  • 网格组件的overscanCountoverscanColumnsCountoverscanRowsCount 。 (改为使用overscanColumnCountoverscanRowCount 。)
  • 将删除列表组件的overscanCount ,以支持动态过扫描方法。
  • direction “水平”和“垂直”值。 (这些已移至layout ,但它们将在版本2中完全删除。)
  • itemData道具(以及传递给项目渲染器的相应的data道具)将被删除,因为对渲染道具API的更改不再需要这样做。
  • useIsScrolling道具(以及传递给项目渲染器的相应isScrolling道具)将被删除,因为对预渲染和显示锁定的更改会使实现起来更加昂贵。
  • 滚动对齐参数将略有变化。 以前命名的“自动”现在将命名为“最小”。 新的默认值将是“智能”(而不是“自动”)。

请注意,鉴于其他计划中的更改,上述一些不推荐使用的道具可能仍然不相关,但是出于完整性考虑,我还是在这里列出它们。

👋 help wanted 💬 discussion

最有用的评论

在我们的案例中,水平列表广泛用于移动设备。 我们也将它们用于像控件一样的无限滚动的传送带。 IMO必须在移动设备上放东西。

所有44条评论

在我们的案例中,水平列表广泛用于移动设备。 我们也将它们用于像控件一样的无限滚动的传送带。 IMO必须在移动设备上放东西。

感谢您分享用例@istarkov。 这并不是说我不认为水平窗口有_any_个有效的用例。 我只是认为它们不那么常见。 (即使是轮播,很多人都使用不需要“滚动”事件窗口的向左/向右箭头导航。)我认为(对我来说)放弃对v2的支持可能是更好的方法,以帮助抵消一些我计划引入的预渲染,动态大小调整等方面的复杂性。

我对这种更精简的方法感到非常兴奋,该方法将有望导致更简单,更高性能和更简单的代码。

伟大的。 但是我对删除可变大小列表几乎没有顾虑。 您打算用DynamicList替换可变大小列表,但是无法滚动到项目的动态列表问题,这对于某些组件可能是非常有用的功能,并且随着时间的流逝会出现这种要求,因此您无法预测是否反应窗口适合您的需求。
我看到的第二个问题是动态列表性能,如果您可以为动态列表提供与可变大小列表相同的性能,即使您不支持scrollToItem,也可以将其删除,但如果不这样做,开发人员可能会被锁定“动态列表”很慢并且没有滚动到项目支持的奇怪情况,“列表”只有固定的项目高度。

您计划用DynamicList替换可变大小列表,但是无法滚动到项目的动态列表问题

我不认为这是一个固有的局限性,只是当前的实现方式之一。 我对如何提供该功能有一些想法。 我是否有时间解决这个问题,是另一个问题:微笑:

我看到的第二个问题是动态列表性能,如果您可以为动态列表提供与可变大小列表相同的性能,即使您不支持scrollToItem,也可以将其删除,但如果不这样做,开发人员可能会被锁定“动态列表”很慢并且没有滚动到项目支持的奇怪情况,“列表”只有固定的项目高度。

很难说它是否也会表现出色。 好像动态列表将不得不做更多的工作,因此它可能无法很好地执行。 也许差异会很大,也许不会。 我希望能够支持一些我目前不支持的功能,并且我认为我需要缩小范围以添加新功能。 如果您目前对变量列表满意,则没有理由升级到v2(至少在不久的将来)。

@bvaughn这对我来说就像文档!
从去年夏天开始,您一直在从事此工作吗? ;-)

更严重的是-我认为渲染道具在这种情况下是有意义的,即使我不是粉丝。

不,我是今天早上写的😝我已经筋疲力尽了。

我认为在这种情况下,即使我不是粉丝,渲染道具还是有意义的。

您能详细说明为什么您不是粉丝吗?

水平列表/网格支持是否可以像AutoSizer (react-virtualized-auto-sizer)这样的选择功能有意义?

我已经将react-virtualized和react-window都用于水平列表,并且发现react-window API更加简单。 尽管我明确理解过时的必要性,以期希望有一个更简单的API。

网格支持仍在计划中。 选择横向支持,并非并非如此。 我认为那没有道理。

@bvaughn我通常喜欢渲染道具,它们会解决您所概述的问题,但是II认为它们鼓励内联函数,该函数可能包含也可能不包含嵌套逻辑。 here此处的任何故障均落在用户身上。 🙂

你能实现砌体网格吗?

@nikitapilgrim不。我建议您只使用react-virtualizedMasonry组件

https://github.com/bvaughn/react-virtualized/blob/master/docs/Masonry.md

谢谢,但是它的工作只能与虚拟化吗?

@nikitapilgrim是的。 👍
React虚拟化支持很多功能,而React-window不支持。

大大缩小了反应窗口的范围,以专注于使包装更小更快。 😉

如果您需要从react-virtualized中获得功能,我建议您坚持使用它-它仍然是一个很棒的库!

我偶然发现了react-window因为我正在寻找react-virtualized babel 7问题的解决方案。 我正在使用react-virtualized Masonry组件,但在升级babel之后无法使用。

这里不是报告虚拟化问题的地方。

同意@bvaughn。 但是,您自己和@babangsund在上面回复了@nikitapilgrim ,不会在react-window引入Masonry组件,而是使用react-virtualized 。 但是,如果用户使用的是最新的[email protected][email protected] (例如create-react-app ),则react-virtualized不一定有效。

我认为这对于在同一兔子洞下的其他任何人都是有用的信息。
¯\ _(ツ)_ /¯

嘿,我想使用动态大小列表在哪里可以下载版本2,否则我将不得不使用react virtualize?
image

这是我的列表看起来与可变大小列表

这不是一般的支持问题。 请保留有关主题的评论。

反馈表示赞赏

我在类似trello的产品上使用react-window ,这里有一些想法:

渲染道具

由于其简单性并避免了上述缺点,因此这似乎是一个不错的更改。 而且,该api将更类似于react-native的FlatList。 我记得在https://github.com/bvaughn/react-window/issues/85上阅读了讨论

更少的组件
不再支持水平列表

我强烈反对删除horizontal支持和VariableSizeList 。 您可以想象,这是我使用的主要两个。 它们的实施真的负担太大了吗? 如果没有,我希望您可以重新考虑并保留它们。

对于其他更改,我没有任何强烈的意见。 overscanCount删除确实让我有些担心,但是我还没有遇到需要自定义值的用例,因此可能还不错。

嘿@bvaughn! 谢谢你的包裹! 我希望在工作中将版本2纳入我的项目中。 您是否有可能在何时发布此计划?

感谢您提供此库,并分享您的未来发布计划,这对帮助我们减轻技术负担非常有帮助。

是否有使用最近的react-window和更高版本2的WindowScroller行为的“简单”方式?

如果不可能的话,这是否超出了此版本2的范围? 还是可以在以后添加?

我的上下文是我的布局包含一个页脚,使用DynamicSizeList类的现代方法会引入第二个滚动条(一个用于页面,一个用于产品列表)

大包装。 默认情况下,急切地等待动态高度列表-目前,我编写了一堆自定义逻辑,用于将渲染的行高传递回父列表。 希望有了这个新版本,我可以删除该逻辑。 感谢您为此做的工作!

@ltkn @mrdanimal

已经有一种使用窗口滚动器的方法:
https://github.com/bvaughn/react-window/issues/30#issuecomment -428868071

如何在左右两个方向上无限滚动!!!

如果我们有WindowScroller而不依赖于react-virtualized ,那将很棒。 因为背后有目标react-window使得它更高效,更少的代码比较react-virtualized所以,我不希望使用WindowScrollerreact-virtualized 。 而是寻找一个像react-virtualized-auto-sizer这样的独立软件包。

提前致谢。

@prabusamvel hm ..
单独包装的好处是什么?

一直在使用新的DynamicSizeList。 很酷! 我认为,方向类型中将包括“ ttb”和“ btt”(从上到下,从下到上)是一个很大的增强。 当前,尚无清除方法来实现向上滚动的列表,但支持其他所有方向。

@toddmacintyre我找不到此版本2。有人可以指导我吗?

@ muhammedmagdi npm install react-window@next

如果版本2可以支持此处规范所要求的DOM结构,那就太好了-https: //www.w3.org/TR/wai-aria-1.1/#grid,因为#217仍然是我们的问题。 据我所知,您现在对版本2的建议没有。

@mjurkowski @bvaughn yarn add react-window@next安装1.6.0-alpha.1 。 另外,当尝试运行动态列表沙箱示例https://react-window-next.now.sh/#/examples/list/dynamic -size时,它会抛出Error importing GitHub repository: Could not find package.json

以及如何在网格中传递index呢?

我们的应用程序的一部分需要具有可变宽度列标题的网格。 通过使用带有网格的水平可变大小列表并同步两者的滚动,我们已经实现了这一点。

删除水平列表将阻止我们创建该UI(或者至少我们必须重写它以使用2个网格,其中列标题网格只有一行。

下一个产品看起来很棒。 但是我同时需要水平和垂直,因此仅供参考,我创建了自己的https://www.npmjs.com/package/react-infinite-grid-scroller。 使用网格布局,反应钩子,IntersectionObserver和requestIdleCallback。

欢迎反馈。

我感觉支持粘性元素将是对React-window的极大补充。 这是一个非常常见的用例,可以直接用于列表和网格。

该API可能如下所示:

<Grid
    // First 2 columns are sticky
    stickyLeft={2}
    // Last column is not sticky (default value)
    stickyRight={0}
    // First and last rows are sticky
    stickyTop={1}
    stickyBottom={1}
/>

使粘性起作用的两个关键要素是:

  1. 仅卸载粘滞的单元格(如果它们不在轴的窗口内),而不粘滞
  2. 使用position: sticky代替absolute ,并使用margin-x代替lefttop代替不粘滞的轴

如此出色的功能的成本似乎是合理的:

  • 占地面积最小
  • 对性能没有重大影响(仅渲染一些额外的行/列)
  • 浏览器支持很棒,不支持position: sticky只能看到普通版本

如果您认为此用例过于具体而无法支持,那么一个很大的妥协就是仅支持第1点。能够指定是否应渲染单元格可以轻松实现粘性。

如果需要的话,我很乐意提供帮助。

不支持自动测量和更新其尺寸。

我觉得这是一个很大的缺点。 对于我编写的几乎每个网格,我都需要具有3或4个固定宽度的列(用于状态标签,一些元数据,号召性用语等)和1个动态宽度的列,这些列占用剩余的可用空间。

我很欣赏“不支持”并不一定意味着添加其他代码和组件(例如Autosizer)是不可能的-很好地考虑了这些用例并为需要解决方案的人员记录了解决方案动态列,但不希望对它带来的所有负担进行反应虚拟化。

很好地考虑了这些用例,并为需要动态列的人员记录了解决方案,这将是一个很好的选择

完全理解-但实际上,这将需要大量的努力,并且该库一直是爱的劳动(不是有偿的努力)。 不幸的是,我什至没有时间完成我的精简版v2的工作,更不用说更具侵略性了。 😞

很好地考虑了这些用例,并为需要动态列的人员记录了解决方案,这将是一个很好的选择

完全理解-但实际上,这将需要大量的努力,并且该库一直是爱的劳动(不是有偿的努力)。 不幸的是,我什至没有时间完成我的范围很广的v2努力,更不用说更具侵略性了。 😞

是的。 我明白了。 希望这些努力可以由社区主导。

会很好-但以我的经验,这永远不会发生:smile:

我一直无法将WindowScroller与DynamicSizedList一起使用,可能是因为即时渲染使scrollTo不能很好地工作。 新版本有可能吗?

我已经接受了这样的事实,即我没有时间或精力来完成这项工作。 如果有人想介入并完成我开设的分支机构,我们将竭诚欢迎您的帮助。 (有关ListGrid详细信息,请参见问题#6,以支持实时测量。)

@bvaughn
我在叉子上创建了一些讨论,并附带了一些随机注释。
让我知道是否有什么不应该列入清单或不正确。 我会在取得进展时填写清单。

看起来不错

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

相关问题

ajayns picture ajayns  ·  3评论

davalapar picture davalapar  ·  3评论

carolin913 picture carolin913  ·  3评论

delateurj picture delateurj  ·  3评论

janhesters picture janhesters  ·  3评论