React Native - this.state coming as undefined despite being defined?

Viewed 37

Working on a app where the user can input a title, their name and a paragraph to submit a story which is then stored on a Firestore database. However, despite me inputting some text, when I press the submit button to call storeData(), console.log(firebase.firestore.collection('story')) comes as "[object Object]" and console.log(this.state) comes as "undefined", even though I've clearly defined it in the constructor.

import {
  StyleSheet,
  Text,
  View,
  Image,
  TextInput,
  TouchableOpacity,
} from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import firebase from 'firebase';

export default class write extends React.Component {
  constructor() {
    super();
    this.state = {
      title: '',
      author: '',
      story: '',
    };
  }
  storeData() {
    console.log(firebase.firestore.collection('story'));
    console.log(this.state);
    firebase.firestore.collection('story').add({
      Title: this.state.title,
      Author: this.state.author,
      Story: this.state.story,
    });
  }
  render() {
    return (
      <View style={styles.background}>
        <Text style={styles.text}>Write your own story here!</Text>
        <TextInput
          style={styles.text1}
          placeholder="Enter your name"
          onChangeText={(text) => {this.setState({ title: text })}}></TextInput>
        <TextInput
          style={styles.text1}
          placeholder="Give a title to your story"
          onChangeText={(text) => {this.setState({ author: text })}}></TextInput>
        <TextInput
          multiline={true}
          style={styles.text2}
          placeholder="Enter your story here"
          onChangeText={(storytext) => {
            this.setState({ story: storytext });
          }}></TextInput>
        <TouchableOpacity style={styles.button} onPress={this.storeData}>
          <Text>Submit</Text>
        </TouchableOpacity>
      </View>
    );
  }
}```
1 Answers

Functions you pass to event handlers, such as onPress lose their implicitly bound 'this' context, when the function is called, this is set to undefined.

You have two options, you can either explicitly bind the context of 'this' using the bind method, e.g.

 <TouchableOpacity style={styles.button} onPress={this.storeData.bind(this)}>
     <Text>Submit</Text>
 </TouchableOpacity>

Or use an arrow function, which bind the context of 'this' to the scope the function is defined in, e.g.

// Now an arrow function
storeData = () =>  {
    console.log(firebase.firestore.collection('story'));
    console.log(this.state);
    firebase.firestore.collection('story').add({
      Title: this.state.title,
      Author: this.state.author,
      Story: this.state.story,
    });
  }


<TouchableOpacity style={styles.button} onPress={this.storeData}>
     <Text>Submit</Text>
 </TouchableOpacity>
Related