React Native 中 viewDidAppear 的等价物是什么

问题描述

场景:

我有一个 Login.js,我在多个屏幕上显示Modal,无论我在哪里检查用户是否登录用户成功登录后,我使用 LoggedIn 将名为 1 的密钥从 0 更改为 AsyncStorage。现在,当用户成功登录并且 Modal 关闭时,我想重新渲染 scree 用户

因为我有 iOS 背景,所以我们有 viewDidAppear,每次出现 Modal用户打开另一个应用并返回屏幕等时都会运行。

那么,React Native 中的等价物是什么?当 Modal 关闭时,它应该检查 LoggedIn 中的 AsyncStorage 值是否已更改,并且我已经准备好将组件相应地呈现为 LoggedIn 值的值。

代码

我有一个屏幕 Profile.js,我正在查看:

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

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

基于上述状态,我将视图呈现为:

                {
                    !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>
                }

现在,当 Login.js 呈现 Modal 并在成功登录后使用登录时,我将 LoggedIn 的值更改为 1关闭显示 {{ 1}} 屏幕,但当它显示时,视图不会重新渲染。那么,每次出现 Profile.js 视图时我将如何检查和更改状态?

解决方法

React Native 中 viewDidAppear 的等价物是 componentDidUpdate

听起来您正在处理应用程序中的 2 个不同组件,一个 Login 和一个 Modal 组件。

如果您扩展 Modal 组件的可重用性,则一种方法是将回调方法传递给 Modal 组件。

例如

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

,

一旦用户登录(当您验证登录凭据时),您可以将状态变量needLogin 更改为false,这将重新渲染屏幕,前提是状态已连接到您要重新显示的屏幕-渲染

,

首先要清楚react-native的挂载和更新过程。

一个组件会在任何时候重新变红。

  1. 更新父母的道具。
  2. 组件的状态得到更新。

现在来解决您的问题,在满足上述两个条件之前,您的登录组件不会重新呈现,并且当您使用 AsyncStorage 时,它也不是 reactive。 因此,要么您必须使用诸如 redux-persist 之类的反应式存储,要么您必须使用焦点侦听器,我假设您使用的是反应导航,因此该焦点侦听器可能非常适合您。

每当焦点发生变化时,此函数都会触发,因此您无需负责更新组件等。

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/

注意:此焦点侦听器不适用于 react-native 提供的模态,那么您必须使用 react-navigation modal

如果您不想使用任何焦点侦听器或 redux-persist,您可以在打开模态时简单地检查。

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