Fix stale separator props and expose CellRenderer refs

Reviewed By: sahrens

Differential Revision: D5554920

fbshipit-source-id: 4b6ebc88603afeb642b2860c6069f28cb415d8be
This commit is contained in:
Oleg Lokhvitsky 2017-08-08 17:00:06 -07:00 коммит произвёл Facebook Github Bot
Родитель d9db3bc4bf
Коммит ad21ad2559
3 изменённых файлов: 65 добавлений и 20 удалений

Просмотреть файл

@ -129,7 +129,7 @@ type OptionalProps<SectionT: SectionBase<any>> = {
/**
* 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,

Просмотреть файл

@ -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<any>,
/**
* 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<OptionalProps, Props, State> {
inversionStyle: ?StyleObj,
) {
const {
CellRendererComponent,
ItemSeparatorComponent,
data,
getItem,
@ -461,6 +467,7 @@ class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
}
cells.push(
<CellRenderer
CellRendererComponent={CellRendererComponent}
ItemSeparatorComponent={ii < end ? ItemSeparatorComponent : undefined}
cellKey={key}
fillRateHelper={this._fillRateHelper}
@ -1155,6 +1162,7 @@ class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
class CellRenderer extends React.Component {
props: {
CellRendererComponent?: ?ReactClass<any>,
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 &&
<ItemSeparatorComponent {...this.state.separatorProps} />;
if (!CellRendererComponent) {
return (
<View style={inversionStyle} onLayout={onLayout}>
{element}
{itemSeparator}
</View>
);
}
return (
<View onLayout={onLayout} style={inversionStyle}>
<CellRendererComponent
{...this.props}
style={inversionStyle}
onLayout={onLayout}>
{element}
{ItemSeparatorComponent &&
<ItemSeparatorComponent {...this.state.separatorProps} />}
</View>
{itemSeparator}
</CellRendererComponent>
);
}
}

Просмотреть файл

@ -373,22 +373,24 @@ class VirtualizedSectionList<SectionT: SectionBase> 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},