From ad21ad2559049d984e8a57fe489c1f96df9faab1 Mon Sep 17 00:00:00 2001 From: Oleg Lokhvitsky Date: Tue, 8 Aug 2017 17:00:06 -0700 Subject: [PATCH] Fix stale separator props and expose CellRenderer refs Reviewed By: sahrens Differential Revision: D5554920 fbshipit-source-id: 4b6ebc88603afeb642b2860c6069f28cb415d8be --- Libraries/Lists/SectionList.js | 2 +- Libraries/Lists/VirtualizedList.js | 30 +++++++++++-- Libraries/Lists/VirtualizedSectionList.js | 53 ++++++++++++++++------- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/Libraries/Lists/SectionList.js b/Libraries/Lists/SectionList.js index 1f5e54f4e..69301fab1 100644 --- a/Libraries/Lists/SectionList.js +++ b/Libraries/Lists/SectionList.js @@ -129,7 +129,7 @@ type OptionalProps> = { /** * Used to extract a unique key for a given item at the specified index. Key is used for caching * and as the react key to track item re-ordering. The default extractor checks item.key, then - * falls back to using the index, like react does. Note that this sets keys for each item, but + * falls back to using the index, like react does. Note that this sets keys for each item, but * each overall section still needs its own key. */ keyExtractor: (item: Item, index: number) => string, diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index 0638a6b20..ed5565d7c 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -94,6 +94,11 @@ type OptionalProps = { */ inverted?: ?boolean, keyExtractor: (item: Item, index: number) => string, + /** + * Each cell is rendered using this element. Can be a React Component Class, + * or a render function. Defaults to using View. + */ + CellRendererComponent?: ?ReactClass, /** * Rendered when the list is empty. Can be a React Component Class, a render function, or * a rendered element. @@ -442,6 +447,7 @@ class VirtualizedList extends React.PureComponent { inversionStyle: ?StyleObj, ) { const { + CellRendererComponent, ItemSeparatorComponent, data, getItem, @@ -461,6 +467,7 @@ class VirtualizedList extends React.PureComponent { } cells.push( { class CellRenderer extends React.Component { props: { + CellRendererComponent?: ?ReactClass, ItemSeparatorComponent: ?ReactClass<*>, cellKey: string, fillRateHelper: FillRateHelper, @@ -1214,6 +1222,7 @@ class CellRenderer extends React.Component { render() { const { + CellRendererComponent, ItemSeparatorComponent, fillRateHelper, item, @@ -1234,12 +1243,25 @@ class CellRenderer extends React.Component { : this.props.onLayout; // NOTE: that when this is a sticky header, `onLayout` will get automatically extracted and // called explicitly by `ScrollViewStickyHeader`. + const itemSeparator = + ItemSeparatorComponent && + ; + if (!CellRendererComponent) { + return ( + + {element} + {itemSeparator} + + ); + } return ( - + {element} - {ItemSeparatorComponent && - } - + {itemSeparator} + ); } } diff --git a/Libraries/Lists/VirtualizedSectionList.js b/Libraries/Lists/VirtualizedSectionList.js index b9ef50ed1..744701573 100644 --- a/Libraries/Lists/VirtualizedSectionList.js +++ b/Libraries/Lists/VirtualizedSectionList.js @@ -373,22 +373,24 @@ class VirtualizedSectionList extends React.PureComponent< }; } +type ItemWithSeparatorProps = { + LeadingSeparatorComponent: ?ReactClass<*>, + SeparatorComponent: ?ReactClass<*>, + cellKey: string, + index: number, + item: Item, + onUpdateSeparator: (cellKey: string, newProps: Object) => void, + prevCellKey?: ?string, + renderItem: Function, + section: Object, + leadingItem: ?Item, + leadingSection: ?Object, + trailingItem: ?Item, + trailingSection: ?Object, +}; + class ItemWithSeparator extends React.Component { - props: { - LeadingSeparatorComponent: ?ReactClass<*>, - SeparatorComponent: ?ReactClass<*>, - cellKey: string, - index: number, - item: Item, - onUpdateSeparator: (cellKey: string, newProps: Object) => void, - prevCellKey?: ?string, - renderItem: Function, - section: Object, - leadingItem: ?Item, - leadingSection: ?Object, - trailingItem: ?Item, - trailingSection: ?Object, - }; + props: ItemWithSeparatorProps; state = { separatorProps: { @@ -435,6 +437,27 @@ class ItemWithSeparator extends React.Component { }, }; + componentWillReceiveProps(props: ItemWithSeparatorProps) { + this.setState(state => ({ + separatorProps: { + ...this.state.separatorProps, + leadingItem: props.item, + leadingSection: props.leadingSection, + section: props.section, + trailingItem: props.trailingItem, + trailingSection: props.trailingSection, + }, + leadingSeparatorProps: { + ...this.state.leadingSeparatorProps, + leadingItem: props.leadingItem, + leadingSection: props.leadingSection, + section: props.section, + trailingItem: props.item, + trailingSection: props.trailingSection, + }, + })); + } + updateSeparatorProps(newProps: Object) { this.setState(state => ({ separatorProps: {...state.separatorProps, ...newProps},