Search code examples
javascriptreact-nativefetch

Im making a app in react native and i want to fetch some data from a mysql database and show it in a list? But it shows an error


Error: Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s, the componentWillUnmount method,
in Provider (at App.js:51)
in App (created by ExpoRoot)
in RCTView (at NativeAppearance.tsx:4)
in FallbackAppearanceProvider (at src/index.tsx:70)
in AppearanceProvider (created by ExpoRoot)

Fetching data from a database is new to me so i don't know much about it. Can anyone help me with a solution?

This is what i got now:

componentDidMount() {
fetch('http://217.103.142.212:3000/meldingen')
  .then(response => response.json())
  .then(meldingen => console.log(meldingen))

  .then(console.log(meldingen))
  .catch((error) => console.error(error))
  .finally(() => {
    this.setState({ isLoading: false });
  });

}

render() {
const { data, isLoading } = this.state;
return (
  <View>
    <View>
      {isLoading ? <ActivityIndicator /> : (
        <FlatList
          data={data}
          keyExtractor={({ id }, index) => id}
          renderItem={({ item }) => (
            <Text>{item.Soort_Stank}, {item.Intensiteit}</Text>
          )}
        />
      )}

    </View>

  </View>
);

Solution

  • Let's tackle the problem one at the time:

    • State update. You have the following line .then(meldingen => console.log(meldingen)) the problem with this is that it won't return your data. You probably want something like this:
      .then((meldingen) => {
        console.log(meldingen);
        // Return the values, so that you can chain the `.then` statements
        return meldingen;
      })
    

    Your next line is also faulty, .then(console.log(meldingen)) passes undefined to then.

    • The warning about updating an unmounted component: It only means that your component was destroyed by the time the request resolved. The promise is not cancellable, so the best thing you can do is to store on the component (not in state!) wether it is mounted or not:
    constructor() {
      super();
      this.mounted = false;
    }
    
    componentDidMount() {
    
      this.mounted = true;
      // The original fetch
      fetch('http://217.103.142.212:3000/meldingen')
        .then(response => response.json())
        .catch((error) => console.error(error))
        .finally(() => {
          if (this.mounted) {
            this.setState({ isLoading: false });
          }
        });
    }
    
    componentWillUnmount() {
      this.mounted = false;
    }