Reputation: 671
I feel like this is likely due to me not understanding the flow of React, but I've been struggling to figure it out. Have an infinite scroll list.
if Row
is outside of Scroller
it works fine.
However, if Row
is inside of Scroller
, it results in the component constantly re-rendering. 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. Whats the best way to go about this?
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;
Upvotes: 1
Views: 1942
Reputation: 19762
I'm not 100% sure what you're asking, but I think I have an idea...
Render props can be a bit confusing, but they're essentially children
components that are functions. Meaning, the direct child of List
must be a function that accepts an object of parameters and returns JSX. See this react-window gist for more information regarding passing in data to List
and accessing data
from within the child function.
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. 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. 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.
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
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"));
Upvotes: 1