简体   繁体   English

列表组件不断重新渲染

[英]List component continually re-renders

I feel like this is likely due to me not understanding the flow of React, but I've been struggling to figure it out.我觉得这可能是因为我不了解 React 的流程,但我一直在努力弄清楚。 Have an infinite scroll list.有一个无限滚动列表。

if Row is outside of Scroller it works fine.如果RowScroller之外,它可以正常工作。

However, if Row is inside of Scroller , it results in the component constantly re-rendering.但是,如果RowScroller内部,则会导致组件不断地重新渲染。 I was hoping to pass a list into Scroller from the parent component with around a thousand items, but in order to do that, I need Row in Scroller to be able to access the props.我希望将包含大约一千个项目的父组件的列表传递给Scroller ,但为了做到这一点,我需要Scroller中的Row才能访问道具。 Whats the best way to go about this? go 的最佳方法是什么?

import React from "react";
import { FixedSizeList as List } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";

const Scroller = (randomArray) => {
  const Row = ({ index, style }) => (
    <div className={index % 2 ? "ListItemOdd" : "ListItemEven"} style={style}>
      {randomArray[index]}
    </div>
  );

  return (
    <AutoSizer>
      {({ height, width }) => (
        <List
          className="List"
          height={height}
          itemCount={1000}
          itemSize={35}
          width={width}
        >
          {Row}
        </List>
      )}
    </AutoSizer>
  );
};

export default Scroller;


I'm not 100% sure what you're asking, but I think I have an idea...我不是 100% 确定你在问什么,但我想我有一个想法......

Render props can be a bit confusing, but they're essentially children components that are functions. 渲染道具可能有点令人困惑,但它们本质上是作为函数的children组件。 Meaning, the direct child of List must be a function that accepts an object of parameters and returns JSX.也就是说, List的直接子节点必须是一个 function,它接受参数的 object 并返回 JSX。 See this react-window gist for more information regarding passing in data to List and accessing data from within the child function.有关将数据传递到List和从子 function 中访问data的更多信息,请参阅这个react-window gist。

Here's a working demo:这是一个工作演示:

编辑虚拟窗口自定义数据

By design, this child function is supposed to be re-rendered to add/remove items from the DOM as the user scrolls up/down.按照设计,这个子 function 应该在用户向上/向下滚动时重新渲染以从DOM中添加/删除项目。 To view this behavior, right click on an element, like Season Id , within in the codesandbox window and click on "Inspect" -- you may need to do this twice to focus on the targeted element -- then while the mouse is hovered over the codesandbox render window, scroll down.要查看此行为,请右键单击代码框 window 中的元素,例如Season Id ,然后单击“检查”——您可能需要执行此操作两次以关注目标元素——然后将鼠标悬停在代码框呈现 window,向下滚动。 What you'll notice is that items are dynamically added/removed based upon the scroll direction.您会注意到项目是根据滚动方向动态添加/删除的。 So if you're expecting this child function to NOT be re-rendered when the window is scrolled, then you probably shouldn't be using a virtualized list and, instead, should be using pagination.因此,如果您希望在滚动 window 时不会重新渲染这个子 function,那么您可能不应该使用虚拟化列表,而是应该使用分页。


Example.js Example.js

import React from "react";
import { FixedSizeList as List } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";

const Example = ({ dataList }) => (
  <AutoSizer>
    {({ height, width }) => (
      <List
        className="List"
        height={height}
        itemCount={dataList.length}
        itemData={dataList}
        itemSize={265}
        width={width}
      >
        {({ data, index, style }) => {
          const dataItem = data[index];
          return (
            <div
              className={index % 2 ? "ListItemOdd" : "ListItemEven"}
              style={style}
            >
              <h1>Season Id: {dataItem.seasonId}</h1>
              <h2>Form Id: {dataItem._id}</h2>
              <h2>Start Month: {dataItem.startMonth}</h2>
              <h2>End Month: {dataItem.endMonth}</h2>
              <h2>Send Reminders: {dataItem.sentReminders.toString()}</h2>
            </div>
          );
        }}
      </List>
    )}
  </AutoSizer>
);

export default Example;

index.js index.js

import React from "react";
import { render } from "react-dom";
import Example from "./Example";
import dataList from "./data.json";
import "./styles.css";

render(<Example dataList={dataList} />, document.getElementById("root"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM