Fix bug with sticky headers that listen to onLayout

Summary:
Wrapping them in ScrollViewStickyHeader broken the onLayout and would always give y = 0
because it is now relative to the wrapper.

This uses some not-so-great react magic, but fixes the bugs with no aparent side-effects.

Note we also need to kill the StaticRenderer wrapper that ListView introduces. I think this was
probably a premature optimization anyway since there are usually not many headers and they are
usually pretty cheap to render. If people care, they can use `shouldComponentUpdate` with the
rendered components.

Reviewed By: yungsters

Differential Revision: D4654622

fbshipit-source-id: 1ea557ef64327d1f4df53b22fedd678da1549288
This commit is contained in:
Spencer Ahrens 2017-03-03 20:05:50 -08:00 committed by Facebook Github Bot
parent 94a333a2ea
commit 500dd2cff3
2 changed files with 16 additions and 15 deletions

View File

@ -42,6 +42,10 @@ class ScrollViewStickyHeader extends React.Component {
});
this.props.onLayout(event);
const child = React.Children.only(this.props.children);
if (child.props.onLayout) {
child.props.onLayout(event);
}
};
render() {
@ -85,7 +89,8 @@ class ScrollViewStickyHeader extends React.Component {
onLayout={this._onLayout}
style={[child.props.style, styles.header, {transform: [{translateY}]}]}>
{React.cloneElement(child, {
style: styles.fill,
style: styles.fill, // We transfer the child style to the wrapper.
onLayout: undefined, // we call this manually through our this._onLayout
})}
</Animated.View>
);

View File

@ -404,6 +404,8 @@ var ListView = React.createClass({
var rowCount = 0;
var stickySectionHeaderIndices = [];
const {renderSectionHeader} = this.props;
var header = this.props.renderHeader && this.props.renderHeader();
var footer = this.props.renderFooter && this.props.renderFooter();
var totalIndex = header ? 1 : 0;
@ -427,20 +429,14 @@ var ListView = React.createClass({
}
}
if (this.props.renderSectionHeader) {
var shouldUpdateHeader = rowCount >= this._prevRenderedRowsCount &&
dataSource.sectionHeaderShouldUpdate(sectionIdx);
bodyComponents.push(
<StaticRenderer
key={'s_' + sectionID}
shouldUpdate={!!shouldUpdateHeader}
render={this.props.renderSectionHeader.bind(
null,
dataSource.getSectionHeaderData(sectionIdx),
sectionID
)}
/>
);
if (renderSectionHeader) {
bodyComponents.push(React.cloneElement(
renderSectionHeader(
dataSource.getSectionHeaderData(sectionIdx),
sectionID
),
{key: 's_' + sectionID},
));
if (this.props.stickySectionHeadersEnabled) {
stickySectionHeaderIndices.push(totalIndex++);
}