【问题标题】:What is the equivalent of viewDidAppear in React NativeReact Native 中的 viewDidAppear 等价物是什么
【发布时间】:2021-04-05 06:30:46
【问题描述】:

场景:

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

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

那么,什么是 React Native 中的等价物?当模态关闭时,它应该检查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 并关闭显示Profile.js 屏幕的模式,但当它显示它时视图不会重新渲染。那么,每次出现profile.js 视图时如何检查和更改状态?

【问题讨论】:

    标签: javascript reactjs react-native viewdidappear


    【解决方案1】:

    在本机反应中,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 />}
    }
    
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 如果我只在一个屏幕上显示Login.js,那会起作用。我将Login.js 设为Modal 的原因是我想从多个屏幕上显示它。会,它在这种情况下仍然有效吗?
      • 从哪里打开模态框,模态框在你的根文件(app.js)中吗?
      【解决方案3】:

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

      组件将随时重新渲染。

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

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

      每当焦点发生变化时,这个函数都会触发,所以你不需要关心更新组件等。

      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])
      

      【讨论】:

        猜你喜欢
        • 2017-05-05
        • 1970-01-01
        • 1970-01-01
        • 2019-08-13
        • 2020-04-23
        • 1970-01-01
        • 1970-01-01
        • 2016-11-08
        • 2019-03-29
        相关资源
        最近更新 更多