首次登录时的 React-Native 欢迎屏幕
Posted
技术标签:
【中文标题】首次登录时的 React-Native 欢迎屏幕【英文标题】:React-Native Welcome Screen on first login 【发布时间】:2020-01-01 11:32:59 【问题描述】:我正在开发一个 React-Native 应用程序,我想在其中包含一个欢迎屏幕,该屏幕会在用户登录后显示,但仅在第一次出现。我已经使用 React-Native-App-Intro-Slider 开发了欢迎屏幕,它运行良好,但每次用户打开应用时都会显示。
这是我目前拥有的代码。这是 Welcome.js 代码:
import StyleSheet, View, Text, Image, I18nManager, Dimensions from 'react-native';
import AppIntroSlider from 'react-native-app-intro-slider';
import TouchableRipple from 'react-native-paper'
import FastImage from 'react-native-fast-image';
import Icon from 'react-native-vector-icons/FontAwesome5'
import styles from './Welcome.styles';
I18nManager.forceRTL(false);
const slides = [
key: 'k1',
title: '',
text:
'',
video:
'id': 'k1',
'name': '',
'externalUrl': '',
'link': '',
'type': 'video',
'uuid': 'external',
'cover_url': '',
'title-human': '',
'brand-human': '',
,
image: require('../../assets/images/logo.png')
,
key: 'k2',
title: 'Step 1:',
text: '',
video:
'id': 'k2',
'name': '',
'externalUrl': '',
'link': '',
'type': 'video',
'uuid': 'external',
'cover_url': '',
'title-human': '',
'brand-human': '',
,
footer: ''
,
key: 'k3',
title: 'Step 2:',
text: 'Connect your music through your speakers',
video:
'id': 'k3',
'name': '',
'externalUrl': '',
'link': '',
'type': 'video',
'uuid': 'external',
'cover_url': '',
'title-human': '',
'brand-human': '',
,
,
key: 'k4',
title: '',
text: '',
video:
'id': 'k4',
'name': '',
'externalUrl': '',
'link': '',
'type': 'video',
'uuid': 'external',
'cover_url': '',
'title-human': '',
'brand-human': '',
,
,
key: 'k5',
title: 'And lastly...',
image: require('../../assets/images/logo.png'),
text: '',
footer: ''
];
export default class Welcome extends React.Component
constructor(props)
super(props);
this.state =
show_Main_App: false
static navigationOptions = header: null
on_Done_all_slides = () =>
this.setState( show_Main_App: true );
;
on_Skip_slides = () =>
this.setState( show_Main_App: true );
;
_renderItem = ( item ) => (
<View style=styles.mainContent>
<Text style=styles.title>item.title</Text>
item.image == undefined ? (
<>
<View style=styles.videoContainer>
<FastImage style=styles.videoImage resizeMode='cover' source= uri: item.video.cover_url />
<View style=styles.videoDetailsContainer>
<View style=styles.videoTagContainer>
<Text style=styles.videoTagText> </Text>
</View>
<View style=styles.featuredVideoButtonsContainer>
<TouchableRipple
onPress=() => this.props.navigation.navigate( routeName: 'VideoPlayer', key: 'videoPlayer', params: 'item': item.video )
rippleColor='rgba(0, 0, 0, .32)'
>
<View style=styles.videoPlayButton>
<Icon style=styles.videoPlayButtonIcon name='play-circle' size=100 color='#fff' />
<Text style=styles.videoPlayButtonText>Play</Text>
</View>
</TouchableRipple>
</View>
</View>
</View>
<Text style=styles.text>item.text</Text>
</>
) : (
<>
<Image source=item.image style=styles.image resizeMode='contain' />
<View>
<Text style=styles.text>
item.text
</Text>
<Text style=styles.text>
item.footer
</Text>
</View>
</>
)
</View>
);
render()
if (this.state.show_Main_App)
return (
this.props.navigation.replace('Dashboard')
);
else
return (
<AppIntroSlider
renderItem=this._renderItem
slides=slides
onDone=this.on_Done_all_slides
showSkipButton=true
onSkip=this.on_Skip_slides />
);
正如我所说,这完全符合预期。但是,它每次都会出现。这是我的 App.js 代码:
import createStackNavigator, createAppContainer, createBottomTabNavigator from 'react-navigation'
import View, StatusBar, Text from 'react-native'
// import FontAwesome from 'react-native-vector-icons/FontAwesome5'
import IconFontawesome from 'react-native-vector-icons/FontAwesome'
import IconMaterial from 'react-native-vector-icons/MaterialCommunityIcons'
import MenuProvider from 'react-native-popup-menu';
// screens
import Splashscreen from './src/screens/Splashscreen/Splashscreen'
import ProfileSetup from './src/screens/ProfileSetup/ProfileSetup'
import UserCreation from './src/screens/UserCreation/UserCreation'
import Login from './src/screens/Login/Login'
import Signup from './src/screens/Signup/Signup'
import VideoPlayer from './src/screens/VideoPlayer/VideoPlayer'
import VideoProfile from './src/screens/VideoProfile/VideoProfile'
import AudioProfile from './src/screens/AudioProfile/AudioProfile'
import ForgotPassword from './src/screens/ForgotPassword/ForgotPassword'
import Welcome from './src/screens/Welcome/Welcome'
import WhoWatching from './src/screens/WhoWatching/WhoWatching'
// Tabs
import MenuScreen from './src/screens/TabScreens/MenuScreen/MenuScreen'
import HomeScreen from './src/screens/TabScreens/HomeScreen/HomeScreen'
// import DownloadScreen from './src/screens/TabScreens/DownloadScreen/DownloadScreen' // avega : replaced with devices screen
import DeviceScreen from "./src/screens/TabScreens/DeviceScreen/DeviceScreen";
import SearchScreen from './src/screens/TabScreens/SearchScreen/SearchScreen'
// Menu Screens
import AccountScreen from './src/screens/TabScreens/MenuScreen/AccountScreen/AccountScreen'
import AppSettingsScreen from './src/screens/TabScreens/MenuScreen/AppSettingsScreen/AppSettingsScreen'
import CellularDataUsageScreen from './src/screens/TabScreens/MenuScreen/AppSettingsScreen/CellularDataUsageScreen/CellularDataUsageScreen'
import VideoQualityScreen from './src/screens/TabScreens/MenuScreen/AppSettingsScreen/VideoQualityScreen/VideoQualityScreen'
import HelpScreen from './src/screens/TabScreens/MenuScreen/HelpScreen/HelpScreen'
import ManageProfilesScreen from './src/screens/TabScreens/MenuScreen/ManageProfilesScreen/ManageProfilesScreen'
import MyListScreen from './src/screens/TabScreens/MenuScreen/MyListScreen/MyListScreen'
import PrivacyScreen from './src/screens/TabScreens/MenuScreen/PrivacyScreen/PrivacyScreen'
import configureStore from "./src/state/store";
import Provider from "react-redux";
import Root from "native-base";
import DeviceProfile from "./src/screens/DeviceProfile/DeviceProfile";
import DeviceEnroll from "./src/screens/DeviceEnroll/DeviceEnroll";
const DashboardTabNavigator = createBottomTabNavigator(
HomeScreen: HomeScreen,
SearchScreen: SearchScreen,
DeviceScreen: DeviceScreen,
MenuScreen: MenuScreen
,
defaultNavigationOptions: ( navigation ) => (
tabBarIcon: ( focused, horizontal, tintColor ) =>
const routeName = navigation.state;
let iconName;
if (routeName === 'MenuScreen')
iconName = `menu`
else if (routeName === 'HomeScreen')
iconName = `home`
else if (routeName === 'DeviceScreen')
iconName = `television`;
else if (routeName === 'SearchScreen')
iconName = `thermometer`
// return <IconFontawesome name=iconName size=30 color=focused ? '#fff' : '#c0d3d6' />
return <IconMaterial name=iconName size=30 color=focused ? '#fff' : '#c0d3d6' />
,
tabBarLabel: ( focused, tintColor ) =>
const routeName = navigation.state;
let labelName;
if (routeName === 'MenuScreen')
labelName = `Menu`
else if (routeName === 'HomeScreen')
labelName = `Showcase`
else if (routeName === 'DeviceScreen')
labelName = `Devices`
else if (routeName === 'SearchScreen')
labelName = `Store`
return <Text style=focused ? textAlign: 'center', fontSize: 11, color: '#fff', fontWeight: '600', marginTop: -5, marginBottom: 5 : textAlign: 'center', fontSize: 11, marginTop: -5, marginBottom: 5, color: '#C0D3D6' >labelName</Text>
),
tabBarOptions:
activeTintColor: '#ff3402',
inactiveTintColor: '#eaeaea',
style:
backgroundColor: '#00A5AC',
height: 65
,
labelStyle:
color: '#fff'
,
initialRouteName: 'HomeScreen',
navigationOptions:
header: null
)
const AppNavigator = createStackNavigator(
Splashscreen: Splashscreen,
UserCreation: UserCreation,
Login: Login,
Signup: Signup,
ProfileSetup: ProfileSetup,
Dashboard: DashboardTabNavigator,
Account: AccountScreen,
AppSettings: AppSettingsScreen,
VideoQuality: VideoQualityScreen,
CellularDataUsage: CellularDataUsageScreen,
Help: HelpScreen,
ManageProfiles: ManageProfilesScreen,
MyList: MyListScreen,
Privacy: PrivacyScreen,
VideoPlayer: VideoPlayer,
VideoProfile: VideoProfile,
AudioProfile: AudioProfile,
//AudioPlayer: AudioPlayer
ForgotPassword: ForgotPassword,
WhoWatching: WhoWatching,
DeviceProfile: DeviceProfile,
DeviceEnroll: DeviceEnroll,
Welcome: Welcome
,
initialRouteName: 'Splashscreen',
navigationOptions:
header: null
);
const AppContainer = createAppContainer(AppNavigator)
export default class App extends React.Component
store = configureStore();
render ()
return (
<Provider store=this.store>
<Root>
<MenuProvider>
<View style= flex: 1 >
<AppContainer />
<StatusBar translucent backgroundColor='transparent' barStyle='light-content' />
</View>
</MenuProvider>
</Root>
</Provider>
)
如您所见,第一页是启动画面,然后应引导至导览。这是 Splashscreen.js 代码:
import View, Image, ActivityIndicator from 'react-native'
import styles from './Splashscreen.styles'
import AuthHelperMethods from "../../api/auth-helper-methods";
export default class Splashscreen extends Component
static navigationOptions = header: null
componentDidMount ()
setTimeout(() =>
AuthHelperMethods.loggedIn().then((isLoggedIn) =>
if (isLoggedIn)
this.props.navigation.replace('Welcome')
else
this.props.navigation.replace('UserCreation')
)
, 500)
state=
loading: true
;
render ()
return (
<View style=styles.container>
<Image style=styles.logo resizeMode='contain' source=require('../../assets/images/logo.png') />
<ActivityIndicator size=50 color='#00b2ba' />
</View>
)
我不确定如何开始概念化这个组件的想法,即该组件仅在首次登录时显示,或者每次登录时至少显示一次,而不是每次使用应用程序时显示。
有什么想法吗?
【问题讨论】:
每次出现“欢迎”屏幕时,因为您在状态中添加了“show_Main_App”标志,因此每次用户进入屏幕时,它都具有默认状态,因此显示欢迎屏幕。解决方法是您应该在 Redux 中保留“show_Main_App”标志以保留或使用 AsyncStorage。 【参考方案1】:您可以简单地使用localStorage
。您将不得不做一些条件渲染。每当用户启动应用程序时,您都必须执行localStorage.setItem('firstTime', false)
之类的操作。因此,下次用户启动应用时,您只需检查localStorage.getItem('firstTime') === false
是否为假,如果为假,则呈现您的登录页面。
【讨论】:
【参考方案2】:您可以使用 Shared Preferences 来检查是否是第一次登录。
当显示欢迎屏幕时,只需存储 boolean
之类的 showWelcomeScreen
。
在启动时,您可以检查共享首选项并决定是否显示屏幕。
更多信息请查看:Shared Preferences
【讨论】:
【参考方案3】:最简单的方法可能是使用asyncStorage
(https://facebook.github.io/react-native/docs/asyncstorage)
安装后导入:
import AsyncStorage from '@react-native-community/async-storage';
或
import AsyncStorage from 'react-native' //Deprecated, will be removed in the future
在向用户显示欢迎屏幕后,将数据存储在 asyncStorage
中:
storeData = async () =>
try
await AsyncStorage.setItem('welcomeScreenSeen', 'true')
catch (e)
// saving failed
在那之后,登录会检查那个变量,如果它是假的,就跳过你的welcomeScreen。
那么在你的 isLoggedInIf 里面会是:
if (isLoggedIn)
this.props.navigation.replace(this.getData("welcomeScreenSeen")?'ScreenDifferentFromWelcome':'Welcome')
getData 的位置:
getData = async (key) =>
try
const value = await AsyncStorage.getItem(key)
return value
catch(e)
// error reading value
【讨论】:
以上是关于首次登录时的 React-Native 欢迎屏幕的主要内容,如果未能解决你的问题,请参考以下文章
新用户首次登录时强制进行 2 因素身份验证 .NET Core
在 ASP.NET Core 中首次登录时强制重定向到另一个页面
keycloak-connect nodejs / meteor - 仅在首次登录时拒绝访问且仅在 prod