react-nativereact-native-button

React Native Button causing Invariant Invalid


For the life of me, I cannot figure out why this little bit of code will not work!

I have isolated the issue to the Button element (the import statement seems fine).

I am seeing the error "Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Check the render method of Login.

 import React, { ScrollView, Image, StyleSheet, Button } from "react- 
 native";
 import { connect } from "react-redux/native";

 const onButtonClicked = () => {};

class Login extends React.Component {
componentDidMount() {}

render() {
    return (
        <ScrollView
            style={{ flex: 1 }}
            contentContainerStyle={{
                justifyContent: "center",
                alignItems: "center"
            }}
        >
            <Image
                source={require("../../img/coin.png")}
                resizeMode={Image.resizeMode.cover}
                style={Styles.coinLogo}
            />

            <Button title="Login default" onPress={() => {}} />
        </ScrollView>
      );
   }
}

Login.propTypes = {
  dispatch: React.PropTypes.func
};

Login.defaultProps = {
   dispatch: () => {}
};

const Styles = StyleSheet.create({
   coinLogo: {
     marginTop: 50,
     height: 200,
     width: 200
},
loginButton: {
    marginTop: 50
}
});

export default connect(state => ({}))(Login);

Solution

  • This is a nasty issue because the error message is really vague. It has to do (I think) with object destructuring.

    When you destructure an object, say:

    var myObject = {a: 1, b: 2, c: 3};
    
    let {a, b, c, d} = myObject;
    

    Your transpiler does the following:

     let a = myObject.a;
     let b = myObject.b;
     let c = myObject.c;
     let d = myObject.d; // Ah! But we never defined a 'd' key, did we?
    

    And of course, non-existing keys evaluate to undefined without raising an error, so what you get is d having a value of undefined.

    Let's go back to your imports. I think they should look like this:

    import React from 'react'; // The React API moved to the react package, you should be getting an error because of this. See https://github.com/facebook/react-native/releases/tag/v0.26.0 (Unless you are using React Native <= 0.25)
    import { ScrollView, Image, StyleSheet, Button } from "react-native";
    import { connect } from "react-redux"; // As far as I know, the connect is exported directly from 'react-redux', but it might be OK the way you had it.
    

    Now, let's go to your render. We are trying to render a ScrollView, a Image and a Button. RN is raising the error because one of those is being evaluated to undefined, which is not allowed, but it is not telling us which one. You can try and console.log the values of the three and check which one is undefined. However, I strongly think it is the Button, because it was added in RN 0.37, and as I mentioned before in the import of React, you must be running a version of RN previous to the 0.26.0 tag, otherwise the code would have raised a different error.

    Let me know if that is the case.