问题描述
场景:
我有一个 Login.js
,我在多个屏幕上显示为 Modal
,无论我在哪里检查用户是否登录。用户成功登录后,我使用 LoggedIn
将名为 1
的密钥从 0
更改为 AsyncStorage
。现在,当用户成功登录并且 Modal
关闭时,我想重新渲染 scree 用户。
因为我有 iOS 背景,所以我们有 viewDidAppear
,每次出现 Modal
或用户打开另一个应用并返回屏幕等时都会运行。
那么,React Native 中的等价物是什么?当 Modal 关闭时,它应该检查 LoggedIn
中的 AsyncStorage
值是否已更改,并且我已经准备好将组件相应地呈现为 LoggedIn
值的值。
代码:
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的挂载和更新过程。
一个组件会在任何时候重新变红。
- 更新父母的道具。
- 组件的状态得到更新。
现在来解决您的问题,在满足上述两个条件之前,您的登录组件不会重新呈现,并且当您使用 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])