Shukant Pal
Shukant Pal

Reputation: 730

React Native: Error while using built-in button

I am trying to learn React Native and while the sample app works, I get an error, on using the Button component. The error comes in the normal red background on my Android Lollipop 5.1 smartphone.

java.lang.String cannot be cast to
com.facebook.react.uimanager.AccessiblityDelegate$AccessibilityRole

setDelegate
AccessbilityDelegateUtil.java:93

updateViewAccessibility
BaseViewManager.java:260

// and more stack trace was given

App.js contains the following code which does not show any errors in VS Code.

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Button} from 'react-native';

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
  android:
    'This was edited by Shukant Pal for testing',
});

type Props = {};
export default class App extends Component<Props> {
_startGame = () => {

}

_loadExistingGame = () => {

}

_loadTemplateLibrary = () => {

}

_displayAboutUs = () => {

}

render() {
  return (
    <View style={styles.container}>
      <Text>This works</Text>
      <View style={styles.container}>
        <Button onPress={this._startGame} title="New Game" />
      </View>
    </View>
  );
}
}

const styles = StyleSheet.create({
 container: {
   flex: 1,
   justifyContent: 'center',
   alignItems: 'center',
   backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

I did the following checks before posting this question:

  1. Imported Button from react-native

  2. Before onPress={this._startGame} was giving errors. After changing the method declarations from name() to name = () => {} that was resolved. Could anyone explain why? (I am new to React and React Native)

Upvotes: 0

Views: 360

Answers (2)

Jeff Gu Kang
Jeff Gu Kang

Reputation: 4879

You can bind your function if you want to use it without arrow function.

For example.

constructor(props) {
  super(props);

  // This binding is necessary to make `this` work in the callback
  this._startGame = this._startGame.bind(this);
}

_startGame() {
  // Do something
}

Why ?

You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.

This is not React-specific behavior; it is a part of how functions work in JavaScript. Generally, if you refer to a method without () after it, such as onClick={this.handleClick}, you should bind that method.

Official

Your way is class properties in ES7 stage 2 as _startGame = () => {}.

https://borgs.cybrilla.com/tils/es7-class-properties/

And CRNA is including babel-plugin-proposal-class-properties for this syntax. That is how we can use the syntax without additional settings on babel.

https://babeljs.io/docs/en/babel-plugin-proposal-class-properties

Upvotes: 1

Shegun
Shegun

Reputation: 46

Because of the way the javascript "this" keyword works. When using "this" on an event listener the "this" keyword does not refer to the class component anymore it refers to the element which the event was acted upon so that's why you are getting an error.

Check this article out it gives a detailed explanation of the this keyword.

this - Javascript | MDN

Upvotes: 1

Related Questions