Search code examples
javascriptreactjsreact-nativeecmascript-6class-properties

ES6+ / React Native class properties: The first one is undefined


I'm trying to use the panResonder in my React Native app. I tried doing so using class properties instead of constructor and super(). Here is the code:

export default class Deck extends Component {
  panResponder = PanResonder.create({
    onStartShouldSetPanResponder: () => true,
    onPanResponderMove: (event, gesture) => {},
    onPanResponderRelease: () => {}
  });
  state = { panResponder };

  renderCards = () => this.props.data.map(item => this.props.renderCard(item));

  render() {
    return <View>{this.renderCards()}</View>;
  }
}

Unfortunately React is complaining that panResponder is undefined. How is that? Do I have to use a constructor here?

The following code is the only that works for me:

export default class Deck extends Component {
  constructor(props) {
    super(props);

    const panResponder = PanResonder.create({
      onStartShouldSetPanResponder: () => true,
      onPanResponderMove: (event, gesture) => {},
      onPanResponderRelease: () => {}
    });
    this.state = { panResponder };
  }

  renderCards = () => this.props.data.map(item => this.props.renderCard(item));

  render() {
    return <View>{this.renderCards()}</View>;
  }
}

Solution

  • panResponder property is defined. panResponder variable isn't.

    state = { panResponder } refers to panResponder variable. Instead, it should be:

    state = { panResponder: this.panResponder };
    

    Do I have to use a constructor here?

    There's no need for explicit constructor function here because class fields are parts of it. Function scope allows to define a variable and use object literal shorthand. It doesn't provide real benefits here, but if there's no need for panResponder property, it could be omitted in favour of a variable:

    constructor() {
      const panResponder = PanResonder.create({
        onStartShouldSetPanResponder: () => true,
        onPanResponderMove: (event, gesture) => {},
        onPanResponderRelease: () => {}
      });
    
      this.state = { panResponder };
    }