简体   繁体   English

React Native 中的 viewDidAppear 等价物是什么

[英]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.我有一个Login.js ,无论我在哪里放置检查以查看用户是否登录,我都会从多个屏幕显示为Modal After the user successfully login I change a key called LoggedIn to 1 from 0 using AsyncStorage .用户成功登录后,我使用LoggedIn将名为 LoggedIn 的密钥从0 AsyncStorage1 Now when a user successfully logged in and the Modal closes I want to rerender the scree user is on.现在,当用户成功登录并且Modal关闭时,我想重新渲染 scree 用户。

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.因为我在 iOS 有背景,所以我们有viewDidAppear每次有Modal或用户打开另一个应用程序并返回屏幕等时运行。

So, what would be the equivalent of that in React Native?那么,什么是 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.当模态关闭时,它应该检查 LoggedIn 值是否在LoggedIn中更改, AsyncStorage我已经准备好组件以相应地呈现LoggedIn值的值。

Code:代码:

I have a screen Profile.js in which I'm checking:我有一个正在检查的屏幕Profile.js

    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:基于上述 state 我将视图渲染为:

                {
                    !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.现在,当Login.js呈现Modal并在成功登录后使用登录时,我将LoggedIn的值更改为1并关闭显示Profile.js屏幕的模式,但是当它显示它时,视图不会重新呈现。 So, how would I check and change the state every time the profile.js view appears?那么,每次出现profile.js视图时,我将如何检查和更改 state?

An equivalent of viewDidAppear in react native would be componentDidUpdate .在 react native 中相当于viewDidAppear的是componentDidUpdate

Sounds like you are dealing with 2 different components in the app, a Login and a Modal component.听起来您正在处理应用程序中的 2 个不同组件,一个Login和一个Modal组件。

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.如果您扩展Modal Modal

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 />}
}

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用户登录后(验证登录凭据后),您可以将 state 变量 needLogin 更改为 false,这将重新渲染屏幕,前提是 state 已连接到您要重新渲染的屏幕

First of all, you have to be clear in the mounting and updating process in react-native.首先你要清楚react-native中的挂载和更新过程。

A componennt will re-redner whenever.组件将随时重新变红。

  1. Props of the parents get updated.父母的道具得到更新。
  2. State of the component gets updated.组件的 State 得到更新。

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.现在遇到您的问题,在满足上述两个条件之前,您的登录组件不会重新渲染,并且由于您使用的是AsyncStorage ,它也不是reactive的。 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.因此,要么你必须使用一些反应式存储,比如redux-persist ,要么你必须使用焦点监听器,我假设你正在使用 react-navigation 所以这个焦点监听器可能很适合你。

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.每当更改焦点时,此 function 将成为触发器,因此您无需处理更新组件等。

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/ 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注意:此焦点侦听器不适用于 react-native 提供的模态,那么您必须使用react-navigation 模态

If you don't want to use any focus listener or redux-persist you can simply check while opening the modal.如果您不想使用任何焦点侦听器或 redux-persist,您可以在打开模式时简单地检查。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM