Skip to content

Commit

Permalink
Fix bug with sticky headers that listen to onLayout
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sahrens authored and dojiboy9 committed Mar 18, 2017
1 parent 983a86b commit 9bee799
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 15 deletions.
7 changes: 6 additions & 1 deletion Libraries/Components/ScrollView/ScrollViewStickyHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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>
);
Expand Down
24 changes: 10 additions & 14 deletions Libraries/CustomComponents/ListView/ListView.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,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;
Expand All @@ -426,20 +428,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++);
}
Expand Down

0 comments on commit 9bee799

Please sign in to comment.