Chaudhry Talha
Chaudhry Talha

Reputation: 7898

What is the equivalent of viewDidAppear in React Native

Scenario:

I have a Login.js that I show as a Modal from multiple screens wherever I have placed the check to see if a user is logged in or not. After the user successfully login I change a key called LoggedIn to 1 from 0 using AsyncStorage. Now when a user successfully logged in and the Modal closes I want to rerender the scree user is on.

As I have a background in iOS, so there we have viewDidAppear that runs every time there is a Modal or user opens another app and comes back to the screen, etc.

So, what would be the equivalent of that in React Native? When a Modal close it should check if the LoggedIn value is changed in AsyncStorage and I've already prepared the components to render accordingly to the value of LoggedIn value.

Code:

I have a screen Profile.js in which I'm checking:

    AsyncStorage.getItem("LoggedIn").then((value) => {
        if (value === "1") {
            setNeedLogin(true)
        } else {
            setNeedLogin(false)
        }
    });

    const [needLogin, setNeedLogin] = useState(false);

Based on the above state I'm rendering the view as:

                {
                    !needLogin &&
                    <View>
                        <Text>{userName}</Text>
                        <Text>{userEmail}</Text>
                        <TouchableOpacity>
                            <Text>Logout</Text>
                        </TouchableOpacity>
                    </View>
                }
                {
                    needLogin &&
                    <View>
                        <Text>You are not logged in</Text>
                        <Text>Please login or create a new account to see more information.</Text>
                        <TouchableOpacity onPress={() => {
                            alert('I am showing login screen here which is a modal')
                        }}>
                            <Text>Login or Sign Up</Text>
                        </TouchableOpacity>
                    </View>
                }

Now when the Login.js renders the Modal and use logs in upon successful login I change the value of LoggedIn to 1 and close the modal which shows the Profile.js screen but when it shows it the view doesn't rerender. So, how would I check and change the state every time the profile.js view appears?

Upvotes: 2

Views: 864

Answers (3)

Waheed Akhtar
Waheed Akhtar

Reputation: 3187

First of all, you have to be clear in the mounting and updating process in react-native.

A componennt will re-redner whenever.

  1. Props of the parents get updated.
  2. State of the component gets updated.

Now coming to your problem, your login component will not re-render until the above two conditions fulfilled, and as you are using AsyncStorage it is not reactive too. So either you have to use some reactive storage like redux-persist or you have to use focus listeners, I am assuming that you are using react-navigation so this focus listener might be a good fit for you.

Whenever the focus will be changed this function will be a trigger so you don't need to take care of updating the component etc.

import * as React from 'react';
import { View } from 'react-native';

function ProfileScreen({ navigation }) {
  React.useEffect(() => {
    const unsubscribe = navigation.addListener('focus', () => {
      // The screen is focused
      // Call any action
    });

    // Return the function to unsubscribe from the event so it gets removed on unmount
    return unsubscribe;
  }, [navigation]);

  return <View />;
}

https://reactnavigation.org/docs/function-after-focusing-screen/

Note: this focus listener will not work with react-native provided modal then you have to use react-navigation modal

If you don't want to use any focus listener or redux-persist you can simply check while opening the modal.

useEffect(()=>{
   if(modalState){
     AsyncStorage.getItem("LoggedIn").then((value) => {
     if (value === "1") {
        setNeedLogin(true)
     } else {
        setNeedLogin(false)
    }
});
 }
}, [modalState])

Upvotes: 0

Rex Low
Rex Low

Reputation: 2177

An equivalent of viewDidAppear in react native would be componentDidUpdate.

Sounds like you are dealing with 2 different components in the app, a Login and a Modal component.

One way to go about that would be passing a callback method to the Modal component if you extend the reusability of the Modal component.

For example,

class Login extends React.Component {
  
  onLoginDone = props => {
    // do some other things, like authenticate with the props data
  }

  render() {
    <View>
      <Modal onClose={this.onLoginDone} />
    </View>
  }

}

class Modal extends React.Component {

  constructor(props) {
    this.state = {
      isVisible: false
    }
  }

  onClose = () => {
    this.setState({ isVisible: !this.state.isVisible })
    this.props.onClose()
  }

  render() {this.state.isVisible && <View />}
}

Upvotes: 1

Bharath
Bharath

Reputation: 1

Once the user has logged in (when you have validated the login credentials), you can change the state variable needLogin to false, this will re-render the screen, provided the state is connected to the screen that you want to re-render

Upvotes: 0

Related Questions