jimo
jimo

Reputation: 602

TypeError: undefined is not a function ('..._this.setState...')

I'm beginner in React Native (and programming in general), currently trying out a simple location component using google maps API. As I'm trying to fetch the position coordinates to be used with the Map view, I am stuck on the following error.

TypeError: undefined is not a function ('..._this.setState...')

My code:

import Geolocation from '@react-native-community/geolocation';
import { StyleSheet, Text, View } from 'react-native';
import FetchLocation from './components/FetchLocation';
import UsersMap from './components/UsersMap';

export default function App() {
  state = {
    userLocation: null
  }

  getUserLocationHandler=()=> {
    console.log('Pressed the button');
    Geolocation.getCurrentPosition(position =>{
      console.log(position);
      this.setState({
        userLocation:{
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
          latitudeDelta: 0.2922,
          longitudeDelta: 0.2421
        }
      })

    });
  }

  return (
    <View style={styles.container}>
      <FetchLocation onGetLocation={this.getUserLocationHandler}/>
      <UsersMap userLocation={this.state.userLocation}/>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Any ideas in helping me spot the issue would be highly appreciated.

Upvotes: 1

Views: 687

Answers (4)

Michalis Garganourakis
Michalis Garganourakis

Reputation: 2930

setState is part of the API provided to react's class components, and can be used only if you create a class component and extend React.Component. You can find out more about class components and React.Component here.

That said, I strongly recommend you to take a look on react hooks if you are using react version > 16.8, as they provide the ability to use state without the need of creating a class component.

For your code to work properly, you just need to make it a class component:

import React, { Component } from 'react';
import Geolocation from '@react-native-community/geolocation';
import { StyleSheet, Text, View } from 'react-native';
import FetchLocation from './components/FetchLocation';
import UsersMap from './components/UsersMap';

export default class App extends Component {
  state = {
    userLocation: null
  }

  getUserLocationHandler() {
    console.log('Pressed the button');
    Geolocation.getCurrentPosition(position =>{
      console.log(position);
      this.setState({
        userLocation:{
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
          latitudeDelta: 0.2922,
          longitudeDelta: 0.2421
        }
      })

    });
  }

  render() {
    return (
      <View style={styles.container}>
        <FetchLocation onGetLocation={this.getUserLocationHandler}/>
        <UsersMap userLocation={this.state.userLocation}/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

or to use useState hook:

import React, { useState } from 'react';
import Geolocation from '@react-native-community/geolocation';
import { StyleSheet, Text, View } from 'react-native';
import FetchLocation from './components/FetchLocation';
import UsersMap from './components/UsersMap';

export default function App() {
  const [userLocation, setUserLocation] = useState(null);

  const getUserLocationHandler = () => {
    console.log('Pressed the button');
    Geolocation.getCurrentPosition(position =>{
      console.log(position);
      setUserLocation({
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
          latitudeDelta: 0.2922,
          longitudeDelta: 0.2421
      })

    });
  }

  return (
    <View style={styles.container}>
      <FetchLocation onGetLocation={getUserLocationHandler}/>
      <UsersMap userLocation={userLocation}/>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Upvotes: 4

rehab hussien Ali
rehab hussien Ali

Reputation: 89

you need to use useState React hook, in this case defining your state will be something like this : [userLocation, setUserLocation] = useState(null) then to set your state you need to use setUserLocation like this setUserLocation({new location object})

Upvotes: 1

hotpink
hotpink

Reputation: 3226

In order to have state in a function component you need to use the Hooks API. The way you implemented state and also the setState method is exclusive to class components. Please refer to the official docs.

On a related note, the this keyword will also never work in a function component.

Upvotes: 2

David Nogueira
David Nogueira

Reputation: 45

.setState is for class based components only. Your component is functional. Look into React Hooks, specifically useState hook to learn about how to have a state in a functional component.

Upvotes: 1

Related Questions