我有一个模态,当用户访问屏幕时会打开模态,具体取决于用户是否具有令牌。因此,事件的顺序如下所示:
1)屏幕监听用户的到来,并尝试从本地存储中检索令牌
2)如果不存在令牌,则Context API同时打开两个对象。首先是模式本身,其次是模式中的菜单组件(模式中有三个组件,这些组件一次打开一个:“菜单”,“注册”和“登录”)
我遇到的问题是模态以及菜单组件都可以很好地打开,但是新打开的模态被冻结且不可单击。当我在以下代码中将useEffect
更改为useLayoutEffect
时,开始出现此问题:
const PleaseSignIn = props => {
const {
state: { authOpen },
authModalOpen
} = useContext(Context)
useLayoutEffect(() => {
const focusListener = props.navigation.addListener('didFocus', () => {
retrieveToken()
})
return () => {
focusListener.remove()
}
}, [])
const retrieveToken = async () => {
try {
const token = await AsyncStorage.getItem(LOGIN_TOKEN)
if(!token) {
authModalOpen()
}
} catch (err) {
throw new Error(err)
}
}
if(authOpen) {
return (
<View style={styles.container}>
<Auth screen={props.screen} navigation={props.navigation} />
</View>
)
}
return props.children
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
})
export default withNavigationFocus(PleaseSignIn)
useEffect
不会在用户第一次访问屏幕时触发侦听器,而只会在第二次访问时触发。但是,模式一旦打开就可以正常工作。 useLayoutEffect
会在第一次访问时打开模式,但会冻结模式。
我正在使用React Native Modal:
import React, { useContext } from 'react'
import {
View,
Text,
StyleSheet,
Modal,
} from 'react-native'
import { Context } from '../../store/context'
import AuthMenu from './AuthMenu'
import Signup from './Signup'
import Signin from './Signin'
export default Auth = ({ screen, navigation }) => {
const {
state: { authOpen, authMenuOpen, signupOpen, signinOpen },
} = useContext(Context)
return (
<View style={styles.container}>
<Modal
animationType="slide"
transparent={false}
visible={authOpen}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}
>
{authMenuOpen && <AuthMenu screen={screen} navigation={navigation} />}
{signupOpen && <Signup screen={screen} navigation={navigation} />}
{signinOpen && <Signin screen={screen} navigation={navigation} />}
</Modal>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
})
如上所述,当侦听器无法检索令牌时,上下文API会同时打开authOpen
和authMenuOpen
。我认为这不是竞争条件,因为useEffect
对此没有任何问题。
根据类似的issue,我尝试包括以下内容,但没有运气:
useEffect(() => {
if (Platform.OS === 'ios') {
LayoutAnimation.easeInEaseOut();
}
})