Related discussion on bvaughn/react-window/issues/85.
The specific API feature this Gist is exploring is the itemData
prop. This prop provides a way for a component to pass "contextual" list data to an item renderer without adding the overhead of using context. In most cases, a single value is passed (e.g. an array/list) like so:
function ComponentThatRendersAListOfItems({ itemsArray, ...rest }) {
render() {
// Pass items array to the item renderer component as itemData:
return (
<FixedSizeList itemData={itemsArray} {...rest}>
{ItemRenderer}
</FixedSizeList>
);
}
}
// The item renderer is declared outside of the list-rendering component.
// So it has no way to directly access the items array.
function ItemRenderer({ data, index, style }) {
// Access the items array using the "data" prop:
const item = data[index];
return (
<div style={style}>
{item.name}
</div>
);
}
But in some advanced cases, multiple values may be required– in which case a wrapper object can be passed.
react-window
currently passes this wrapper object to item renderers as the data
prop (as shown below) but this has implications on memoization (e.g. shouldComponentUpdate
, React.memo
) since changes to this wrapper item would cause a component to re-render unless the object itself is properly memoized (as shown in the react-window
docs example).
react-window
could spread the itemData
object and pass individual props (as shown in this example) in order to relax this memoization requirement, but this would have the following drawbacks:
- The common use case of passing a single value (e.g. an array or list of items) would require a wrapper object to be passed (e.g.
<List itemData={itemsArray} {...rest} />
would become<List itemData={{itemsArray}} {...rest} />
). - This could lead to naming conflicts if your
itemData
prop defined an attribute that List itself reserved (e.g.index
,style
). - Related to the above drawback, newly added item renderer props would become backwards breaking changes, since any new prop may clash with a pre-existing user-defined
itemData
prop. This could lead to unnecessary version fragmentation.