'Calling a function when opening a react-native screen

I'm trying to load a JSON from AsyncStorage every time a user opens one of my react-native screens (I'm using StackNavigator). This JSON contains information on what my states should be set to.

How can I call a function that runs every time this screen is opened?

Further info: I've written a function that updates my states according to a JSON loaded from AsyncStorage. The function works perfectly when called from a button, but when the function is called from render(), part of my screen freezes and some buttons are not touchable anymore. Strangely only TextInput still works.



Solution 1:[1]

use componentWillMount() method. This will execute automatically before render() method gets triggered.

class Sample extends Component{
    state = {data : []};
    componentWillMount(){
        this.setState({data : inputObject});
    }
    render(){
        return(
            <View>
            //you can render the data here
            </View>
        );
    }
}

import { useEffect, useState } from 'react';

const Sample = () => {
    const [state, setState] = useState([]);
    useEffect(() => {
        setState(inputObject);
    }, [])

    return(
         <View>
         //you can render the data here
         </View>
    );

}

Reference: https://facebook.github.io/react/docs/react-component.html#componentwillmount

Solution 2:[2]

If you want to handle back button page navigation then you need to listen to the navigation event once when the component has mounted, use the code below for the same.

componentDidMount = () => {
    this.focusListener = this.props.navigation.addListener('focus',
       () => { 
               console.log('focus is called'); 
              //your logic here.
       }
     );
}

Solution 3:[3]

This can be easily accomplished using 'withNavigationFocus' , found in the react native documentation here

import React, { Component } from 'react';
import { View } from 'react-native';
import { withNavigationFocus } from 'react-navigation';

class TabScreen extends Component {
  componentDidUpdate(prevProps) {
    if (prevProps.isFocused !== this.props.isFocused) {
      // Use the `this.props.isFocused` boolean
      // Call any action
    }
  }

  render() {
    return <View />;
  }
}

// withNavigationFocus returns a component that wraps TabScreen and passes
// in the navigation prop
export default withNavigationFocus(TabScreen);

Solution 4:[4]

You could use a hook approach:

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

I literally just copied the first example of the documentation, but it's a very good one. If you want continue reading: https://reactjs.org/docs/hooks-effect.html

Solution 5:[5]

I used "onLayout" method inside the view.

read the doc

onLayout: Invoked on mount and on layout changes.

export default function Login({ navigation }) {

  const executeOnLoad = () => {
    console.log("view has loaded!");
  };

  return (
    <View style={styles.container} onLayout={executeOnLoad}>
    --- layout code here
    </View>
  );
}

Solution 6:[6]

Since you are dealing with the screen, I will suggest you use useFocusEffect hooks.

example:

const ExampleScreen = () => {
    // your code here
    useFocusEffect(useCallback(() => {
       // your logic goes here
    }, []))
    return (
        <View>
           {/* render your content here */}
        </View>
    )
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ibrahimj
Solution 2 manish kumar
Solution 3 Jar
Solution 4 Felix
Solution 5 Daniel Cettour
Solution 6 Ibrahimj