我正在使用反应窗口来实现聊天消息列表,但我在尝试为每个项目设置权限时遇到了困难itemSize。碰巧的是,基于文本长度和窗口宽度的聊天消息并不总是有前缀高度(或者我可以用简单的方式计算的高度)。
我目前正在使用 aVariableSizeList并且代码如下所示
<AutoSizer>
{({ height, width }) => (
<List
height={height}
itemCount={messages.length}
itemSize={(index) => messages[index].isReply ? 118 : 79} /* THIS IS CURRENTLY WRONG, DOESN'T PICK ALL CASES!*/
width={width}
>
{({ index, style }) => (
<ChatMessage
key={index}
style={style}
...
/>
)}
</List>
)}
Run Code Online (Sandbox Code Playgroud)
有没有办法将列表行的项目高度设置为其内容的实际高度?
我被困在这里进行一个测试,我想验证在滚动浏览由react-window导入的列表组件后,正在渲染不同的项目。该列表位于一个表格组件内,该组件保存了 React 上下文中的滚动位置,这就是我需要测试整个表格组件的原因。
不幸的是,滚动事件似乎没有效果,列表仍然显示相同的项目。
测试看起来像这样:
render(
<SomeProvider>
<Table />
</SomeProvider>
)
describe('Table', () => {
it('scrolls and renders different items', () => {
const table = screen.getByTestId('table')
expect(table.textContent?.includes('item_A')).toBeTruthy() // --> true
expect(table.textContent?.includes('item_Z')).toBeFalsy() // --> true
// getting the list which is a child component of table
const list = table.children[0]
fireEvent.scroll(list, {target: {scrollY: 100}})
expect(table.textContent?.includes('item_A')).toBeFalsy() // --> false
expect(table.textContent?.includes('item_Z')).toBeTruthy() // --> false
})
})
Run Code Online (Sandbox Code Playgroud)
任何帮助将非常感激。
我一直在用 Electron (Chrome) 和 React 实现一个聊天客户端。我们的首要任务是速度。因此,我们应该使用虚拟化列表组件(也称为“缓冲渲染”或“窗口渲染”)。我们已经探索了 react-virtualized、react-window 和 react-infinite 等。
所有这些组件的一个共同点是,如果支持可变高度的列表元素,则需要提前知道高度。现在,有些聊天很长,有些很短,这对我们来说是一个挑战。(由于 EXIF 数据和 ffprobe,图像和视频很容易)。
因此,我们面临着测量高度的挑战,同时也竭力追求卓越的性能。一种明显的技术是将元素放在浏览器容器中,离开视口,执行测量,然后呈现列表。但这在性能要求方面伤害了我们。像 react-virtualized/CellMeasurer(不再由原作者维护)和 react-window 之类的软件使我们采用了这种技术,内置于库中,但性能有点慢且不可靠。一个可能更高效的类似想法是使用后台电子浏览器窗口来进行渲染和测量,但我的直觉是这不会更快。
我认为必须有一些解决的方法可以根据自动换行、最大宽度和字体规则提前确定字符串高度。
我目前的想法是使用像string-pixel-width这样的库,以便在我们通过 API 获取文本数据后立即计算行高。基本上,该库使用这段代码来生成字符宽度 [*] 的映射。然后,一旦我们知道每个文本的宽度,当它最大化计算出的最大行宽时,我们将每行分开,最后通过行数推断列表元素的高度。由于断字,它需要一点点算法摆弄,但有库可以帮助解决这个问题 - css-line-break似乎很有希望。
[*] 我们将不得不稍微修改它以考虑所有 Unicode 字符范围,但这是微不足道的。
我还没有完全探索的一些选项包括 python weasyprint 项目和 facebook-yoga 项目。我愿意接受你的想法!
weasyprint electron react-virtualized react-infinite react-window
我正在使用(和材料 UI 表)react-window创建虚拟表react-table 7。
我嵌入了 FixedSizeList 而不是 TableBody。像这样的东西:
<TableBody {...getTableBodyProps()}>
<FixedSizeList
height={listHeight}
itemCount={rows.length}
itemSize={rowHeight}
>
{RenderRow}
</FixedSizeList>)
</TableBody>
Run Code Online (Sandbox Code Playgroud)
RenderRow 返回 TableRows。像这样的东西:
const RenderRow = React.useCallback( ({ index, style }) =>
{
const row = rows[index];
prepareRow(row);
const rowProps = row.getRowProps();
return (<TableRow
{...row.getRowProps({
style,
})} />);
}
Run Code Online (Sandbox Code Playgroud)
由于react-window工作原理,它创建了几个divs 来实现列表滚动,根据需要动态嵌入所需的 TableRow,从而导致输出 react js 警告。
webpack-internal:///490:506 Warning: validateDOMNesting(...): <tr> cannot appear as a child of <div>
只是忽略这个警告,不是我想做的事情,因为它可能会导致其他警告不被注意。(我也不想在测试时使用发布版本)
那么是否有可能阻止发出此警告?或者是否可以react-window用于表行,而不会收到此警告?
更新:尝试设置innerElementType到 …
我有一个固定的列表和网格,使用react-window、infinite loader和auto sizer。它工作正常,但我希望在列表/网格开始之前附加一个组件(例如,搜索框和按钮)。实现这一目标的正确方法是什么?我希望这个组件与固定列表一起滚动而不是单独滚动。我之前只是渲染组件已经厌倦了,但是它不在固定列表容器中并且不会随它滚动。
{/* WANT TO ADD SOME SORT OF COMPONENT HERE SO IT CAN SCROLL WITH LIST */}
{/* CAN'T IN HERE BECAUSE ITS NOT INSIDE THE FIXED CONTAINER SO IT SCROllS SEPARATELY */}
<AutoSizer>
{({ height, width }) => (
<InfiniteLoader
isItemLoaded={index => index < stateData.data.length}
itemCount={stateData.data.length + 1}
loadMoreItems={loadMoreProducts}
>
{({ onItemsRendered, ref }) => (
<FixedSizeList
onItemsRendered={onItemsRendered}
ref={ref}
height={height}
itemCount={stateData.data.length + 1}
itemSize={350}
width={width}
>
{/* WANT TO ADD SOME …Run Code Online (Sandbox Code Playgroud) 在可搜索的反应选择下拉列表中呈现大量数据的最佳方法是什么?我研究过窗口化,其中仅为在视口中可见的项目创建 DOM 节点。这可以通过使用react-window包和react-select来完成。但是,我想知道是否有比这更好的方法。
这是使用react-window和react-select的窗口实现
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Select from "react-select";
import { FixedSizeList as List } from "react-window";
import "./styles.css";
const options = [];
for (let i = 0; i < 10000; i = i + 1) {
options.push({ value: i, label: `Option ${i}` });
}
const height = 35;
class MenuList extends Component {
render() {
const { options, children, maxHeight, getValue } = this.props;
const [value] = getValue();
const …Run Code Online (Sandbox Code Playgroud) 我正在尝试输入传递给 Row 函数的以下两个参数。
//https://github.com/bvaughn/react-window
import * as React from "react";
import styled from "styled-components";
import { FixedSizeList as List } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";
const StyledSection = styled.section`
width: 100vw;
height: 100vh;
background: #C0C0C0;
`;
const Row = ({ index, style }) => (
<div className={index % 2 ? 'ListItemOdd' : 'ListItemEven'} style={style}>
Row {index}
</div>
);
const Scroller = () => {
return (
<StyledSection>
<AutoSizer>
{({ height, width }) => {
return (
<List height={height} width={width} …Run Code Online (Sandbox Code Playgroud) 我有一个react-table v7(带有粘性页眉和页脚),它使用react-window呈现数千个虚拟化行。
一个新的要求需要表也有粘性列,但我不能让它工作,因为反应窗口添加了几个嵌套的 div 来进行虚拟化,破坏了列的粘性。
已经有一个钩子(https://github.com/GuillaumeJasmin/react-table-sticky)允许创建粘性列,但一旦使用了react-window,它也会中断;一些开发人员指出了一些很好的解决方法,但页脚将不再粘住(https://github.com/GuillaumeJasmin/react-table-sticky/issues/5)。
在此阶段,我还尝试并排使用两个表(一个用于粘性列,一个用于其余列),但考虑到应用的虚拟化,向上/向下滚动时行会不同步。我还尝试使用另一个虚拟化组件(https://github.com/bvaughn/react-virtualized),但遇到了同样的问题。
有没有人遇到过相同或类似的问题并找到了让它发挥作用的方法?
提前致谢。
我正在尝试使用 react-window-infinite-loader 在 material-ui 自动完成下拉列表中显示无限滚动列表。当我滚动到列表底部时,我想从服务器获取下一页项目。我创建了一个代码和框示例,它将用于虚拟化列表的material-ui 自动完成示例与react-window-infinite-loader 示例相结合。当我滚动到列表底部时,会加载下一页数据,但是某些原因导致列表滚动回顶部。加载新数据后如何保持滚动位置?
谢谢!
我正在尝试实现react-window 但我不确定如何传入一个具有自己属性的组件
如果我有这样的事情
{
items.map(
(item, index) => {
<MyComponent
key={key}
item={item}
/>;
}
);
}
Run Code Online (Sandbox Code Playgroud)
如何制作变量列表?
该示例未显示如何执行此操作
import { VariableSizeList as List } from 'react-window';
// These row heights are arbitrary.
// Yours should be based on the content of the row.
const rowHeights = new Array(1000)
.fill(true)
.map(() => 25 + Math.round(Math.random() * 50));
const getItemSize = index => rowHeights[index];
const Row = ({ index, style }) => (
<div style={style}>Row {index}</div>
);
const Example = () …Run Code Online (Sandbox Code Playgroud) react-window ×10
reactjs ×8
javascript ×2
electron ×1
list ×1
material-ui ×1
react-select ×1
react-table ×1
resize ×1
sticky ×1
typescript ×1
weasyprint ×1