Skip to content

Commit

Permalink
fix: First press not working after pull to refresh (#30291)
Browse files Browse the repository at this point in the history
Summary:
According to #20011, the first onPress will not work after pull to refresh.

Dive into the code, found out that is because the state `isTouching` in `Libraries/Components/ScrollResponder.js` is not updated after the pull to refresh.

Update the `isTouching` state in `scrollResponderHandleResponderRelease` to fix this.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[iOS] [Fixed] - First press not working after pull to refresh

Pull Request resolved: #30291

Test Plan:
### Before
- The first onPress fail
![ezgif-4-c6aa5383e898](https://user-images.githubusercontent.com/48589760/97789482-cd4c4100-1bfb-11eb-8a6b-649e8a966b99.gif)
### After
- The first onPress success
![ezgif-4-195f9f6c302e](https://user-images.githubusercontent.com/48589760/97789488-da693000-1bfb-11eb-9a87-f005e61b8ad0.gif)

Eli:
I tested this myself internally using this code sample:

```
'use strict';

import PlaygroundRoute from 'PlaygroundRoute';
import type {SurfaceProps} from 'Surface';
import TetraText from 'TetraText';
import TetraView from 'TetraView';
import {TouchableOpacity, Text, View, ScrollView, RefreshControl, StyleSheet} from 'react-native';
import * as React from 'react';

type Props = SurfaceProps<PlaygroundRoute>;

class App extends React.Component<{}> {
  constructor() {
    super();
    this.state = {refreshing: true, items: []};
  }

  componentDidMount() {
    this.refresh();
  }

  refresh = () => {
    this.setState({
      refreshing: true,
      items: [],
    });

    setTimeout(
      () =>
        this.setState({
          refreshing: false,
          items: [0, 1, 2, 3, 4, 5],
        }),
      1500,
    );
  };

  renderItem = ({item}) => {
    return (
      <TouchableOpacity onPress={() => alert('pressed!')} key={`${item}`}>
        <Text style={{width: '100%', height: 48, backgroundColor: 'white'}}>
          {item}
        </Text>
        <View style={{width: '100%', height: 1, backgroundColor: 'gray'}} />
      </TouchableOpacity>
    );
  };

  render() {
    return (
      <View style={{flex: 1, padding: 48}}>
        <ScrollView
          style={{
            flex: 1,
            backgroundColor: '#aaa',
            borderColor: 'gray',
            borderWidth: 1,
          }}
          keyExtractor={item => `${item}`}
          refreshControl={
            <RefreshControl
              refreshing={this.state.refreshing}
              onRefresh={this.refresh}
            />
          }>
          {this.state.items.map(item => this.renderItem({item}))}
        </ScrollView>
      </View>
    );
  }
}

export default function Playground(props: Props): React.Node {
  return (
    <App />
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 10,
    paddingTop: 30,
  },
});
```

{F351458967}

Reviewed By: appden

Differential Revision: D25574927

Pulled By: TheSavior

fbshipit-source-id: 7abf8a2f947d94150419e51d46a19e792441c981
  • Loading branch information
rnike authored and facebook-github-bot committed Dec 16, 2020
1 parent 9f05544 commit c495061
Showing 1 changed file with 1 addition and 0 deletions.
1 change: 1 addition & 0 deletions Libraries/Components/ScrollResponder.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ const ScrollResponderMixin = {
* Invoke this from an `onResponderRelease` event.
*/
scrollResponderHandleResponderRelease: function(e: PressEvent) {
this.state.isTouching = e.nativeEvent.touches.length !== 0;
this.props.onResponderRelease && this.props.onResponderRelease(e);

if (typeof e.target === 'number') {
Expand Down

0 comments on commit c495061

Please sign in to comment.