如何仅在第一次使用时显示屏幕?
How to show a screen only on first time use?
我试图只显示一次许可协议屏幕。在该屏幕上,有一个 ACCEPT
按钮,单击后 - 它会将值保存到 AsyncStorage
。
在 app.js 中,然后我在 AsyncStorage
中检查该键的值并采取相应的行动。
我的问题是,当我希望许可协议显示时,登录屏幕总是先显示。
我认为这是一个异步问题,但不确定如何解决它。
我确实尝试在 useState
中最初将 loading
设置为 true
,并且此方法有效。
但是一旦我第一次接受协议然后重新加载应用程序 - 我会在重定向到登录屏幕之前快速看到许可协议屏幕一秒钟 - 不太理想。
控制台日志按预期打印值,但我认为导航在 useEffect 逻辑完成之前呈现。
App.js
function App() {
const [loading, setLoading] = useState(false);
useEffect(() => {
load();
}, []);
const load = async () => {
await AsyncStorage.getItem('isAgreementAccepted').then(result => {
console.log('RES: ', result)
if (result == null) {
setLoading(true);
} else {
setLoading(false);
}
})
}
return (
<NavigationContainer>
<Stack.Navigator>
{loading && <Stack.Screen
name="EndUserAgreement"
component={EndUserAgreementScreen}
options={{ headerShown: false }}
/>}
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
您需要做的是在 Stack.Navigator
.
内正常渲染屏幕
并且一旦你得到一个正值就知道这是用户第一次打开应用程序,你必须正常导航到那个屏幕,如下代码所示:
import { useNavigation } from '@react-navigation/native';
function App() {
const [loading, setLoading] = useState(false);
const navigation = useNavigation();
useEffect(() => {
load();
}, []);
const load = async () => {
await AsyncStorage.getItem('isAgreementAccepted').then(result => {
console.log('RES: ', result)
if (result == null) {
navigation.navigate('EndUserAgreement');
await setLocalStoreData('isAgreementAccepted', 'true');
}
});
}
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="EndUserAgreement"
component={EndUserAgreementScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
就像你说的,你 Stack.screens 在设置加载状态之前渲染,所以你是登录屏幕自己加载,然后一旦加载设置为 true 你的 endUserAgreement 屏幕正在加载- 但您的导航 (react-navigation?) 不会自动切换您的路线
您可以:
使用 useNavigation
hook & .navigate() 导航到 endUserAgreement 屏幕(在这种情况下呈现两个 Stack.screen
,并在 Stack.Navigator
上设置 initialRouteName
至 'login')
如果存储调用 returns null,则只保留 endUserAgreement
屏幕,这将强制导航仅显示该屏幕 - 类似于:
{loading ? (
<Stack.Screen
name="EndUserAgreement"
component={EndUserAgreementScreen}
options={{ headerShown: false }}
/>
) : (
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
{/* ... other screens here */}
)}
- 在存储调用完成之前显示加载屏幕,然后根据其结果设置 initialRouteName:
const [loading, setLoading] = useState(null)
const load = async () => {
await AsyncStorage.getItem('isAgreementAccepted').then(result => {
console.log('RES: ', result)
if (result == null) {
setLoading(true);
} else {
setLoading(false);
}
})
}
return (
<NavigationContainer>
{loading === null ? (
<LoadingScreen />
) : (
<Stack.Navigator initialRouteName={loading ? 'EndUserAgreement' : 'login'}>
<Stack.Screen
name="EndUserAgreement"
component={EndUserAgreementScreen}
options={{ headerShown: false }}
/>}
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
所以我们默认为 null
加载状态,显示加载组件,直到它被设置为 true 或 false,然后将初始路由名称设置为正确的屏幕名称。
我试图只显示一次许可协议屏幕。在该屏幕上,有一个 ACCEPT
按钮,单击后 - 它会将值保存到 AsyncStorage
。
在 app.js 中,然后我在 AsyncStorage
中检查该键的值并采取相应的行动。
我的问题是,当我希望许可协议显示时,登录屏幕总是先显示。
我认为这是一个异步问题,但不确定如何解决它。
我确实尝试在 useState
中最初将 loading
设置为 true
,并且此方法有效。
但是一旦我第一次接受协议然后重新加载应用程序 - 我会在重定向到登录屏幕之前快速看到许可协议屏幕一秒钟 - 不太理想。
控制台日志按预期打印值,但我认为导航在 useEffect 逻辑完成之前呈现。
App.js
function App() {
const [loading, setLoading] = useState(false);
useEffect(() => {
load();
}, []);
const load = async () => {
await AsyncStorage.getItem('isAgreementAccepted').then(result => {
console.log('RES: ', result)
if (result == null) {
setLoading(true);
} else {
setLoading(false);
}
})
}
return (
<NavigationContainer>
<Stack.Navigator>
{loading && <Stack.Screen
name="EndUserAgreement"
component={EndUserAgreementScreen}
options={{ headerShown: false }}
/>}
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
您需要做的是在 Stack.Navigator
.
并且一旦你得到一个正值就知道这是用户第一次打开应用程序,你必须正常导航到那个屏幕,如下代码所示:
import { useNavigation } from '@react-navigation/native';
function App() {
const [loading, setLoading] = useState(false);
const navigation = useNavigation();
useEffect(() => {
load();
}, []);
const load = async () => {
await AsyncStorage.getItem('isAgreementAccepted').then(result => {
console.log('RES: ', result)
if (result == null) {
navigation.navigate('EndUserAgreement');
await setLocalStoreData('isAgreementAccepted', 'true');
}
});
}
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="EndUserAgreement"
component={EndUserAgreementScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
就像你说的,你 Stack.screens 在设置加载状态之前渲染,所以你是登录屏幕自己加载,然后一旦加载设置为 true 你的 endUserAgreement 屏幕正在加载- 但您的导航 (react-navigation?) 不会自动切换您的路线
您可以:
使用
useNavigation
hook & .navigate() 导航到 endUserAgreement 屏幕(在这种情况下呈现两个Stack.screen
,并在Stack.Navigator
上设置initialRouteName
至 'login')如果存储调用 returns null,则只保留
endUserAgreement
屏幕,这将强制导航仅显示该屏幕 - 类似于:
{loading ? (
<Stack.Screen
name="EndUserAgreement"
component={EndUserAgreementScreen}
options={{ headerShown: false }}
/>
) : (
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
{/* ... other screens here */}
)}
- 在存储调用完成之前显示加载屏幕,然后根据其结果设置 initialRouteName:
const [loading, setLoading] = useState(null)
const load = async () => {
await AsyncStorage.getItem('isAgreementAccepted').then(result => {
console.log('RES: ', result)
if (result == null) {
setLoading(true);
} else {
setLoading(false);
}
})
}
return (
<NavigationContainer>
{loading === null ? (
<LoadingScreen />
) : (
<Stack.Navigator initialRouteName={loading ? 'EndUserAgreement' : 'login'}>
<Stack.Screen
name="EndUserAgreement"
component={EndUserAgreementScreen}
options={{ headerShown: false }}
/>}
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
所以我们默认为 null
加载状态,显示加载组件,直到它被设置为 true 或 false,然后将初始路由名称设置为正确的屏幕名称。