로그인 화면으로 반응 탐색
react-navigation을 사용하여 탭 바와 헤더가없는 초기 로그인 화면을 만들려고합니다. 일단 사용자가 성공적으로 인증되면 탭바, 헤더 및 뒤로 버튼 옵션이없는 LISTRECORD라는 다른 화면으로 이동합니다. 누구든지 이것에 대한 경험이 있고 공유 할 수 있습니까?
요약하면, react-navigation으로 달성하고자하는 것이 아래에 설명되어 있습니다.
화면 1 : 로그인 화면 (헤더 및 탭바 없음)
인증 됨 ...
화면 2 : LISTRECORD (헤더, 탭바 및 뒤로 버튼 없음)
탭 바에 는 화면 3, 화면 4로 이동하기위한 다른 탭도 포함되어 있습니다.
2017 년 10 월 나는 이것이 엄청나게 혼란스러워서 위에서 아래로 시작하는 내 솔루션입니다.
새 프로젝트를 시작하고 말 그대로이 모든 것을 붙여넣고 나중에 공부하는 것이 좋습니다. 나는 코드에 대해 큰 시간 동안 주석을 달았으므로 특정 영역에 갇혀 있다면 컨텍스트가 당신이 궤도로 돌아 오는 데 도움이 될 수 있습니다.
이 게시물은 다음 방법을 보여줍니다.
- react-navigation을 실행하기 위해 React Native를 완전히 설정
- Redux와 올바르게 통합
- Android 뒤로 버튼 처리
- Nest Stack 내비게이터
- 하위에서 상위 내비게이터로 이동
- 탐색 스택 재설정
- 하위에서 상위 (중첩)로 탐색하는 동안 탐색 스택 재설정
index.js
import { AppRegistry } from 'react-native'
import App from './src/App'
AppRegistry.registerComponent('yourappname', () => App)
src / App.js (모든 조각을한데 모으기 때문에 가장 중요한 파일입니다)
import React, { Component } from 'react'
// this will be used to make your Android hardware Back Button work
import { Platform, BackHandler } from 'react-native'
import { Provider, connect } from 'react-redux'
import { addNavigationHelpers } from 'react-navigation'
// this is your root-most navigation stack that can nest
// as many stacks as you want inside it
import { NavigationStack } from './navigation/nav_reducer'
// this is a plain ol' store
// same as const store = createStore(combinedReducers)
import store from './store'
// this creates a component, and uses magic to bring the navigation stack
// into all your components, and connects it to Redux
// don't mess with this or you won't get
// this.props.navigation.navigate('somewhere') everywhere you want it
// pro tip: that's what addNavigationHelpers() does
// the second half of the critical logic is coming up next in the nav_reducers.js file
class App extends Component {
// when the app is mounted, fire up an event listener for Back Events
// if the event listener returns false, Back will not occur (note that)
// after some testing, this seems to be the best way to make
// back always work and also never close the app
componentWillMount() {
if (Platform.OS !== 'android') return
BackHandler.addEventListener('hardwareBackPress', () => {
const { dispatch } = this.props
dispatch({ type: 'Navigation/BACK' })
return true
})
}
// when the app is closed, remove the event listener
componentWillUnmount() {
if (Platform.OS === 'android') BackHandler.removeEventListener('hardwareBackPress')
}
render() {
// slap the navigation helpers on (critical step)
const { dispatch, nav } = this.props
const navigation = addNavigationHelpers({
dispatch,
state: nav
})
return <NavigationStack navigation={navigation} />
}
}
// nothing crazy here, just mapping Redux state to props for <App />
// then we create your root-level component ready to get all decorated up
const mapStateToProps = ({ nav }) => ({ nav })
const RootNavigationStack = connect(mapStateToProps)(App)
const Root = () => (
<Provider store={store}>
<RootNavigationStack />
</Provider>
)
export default Root
src / navigation / nav_reducer.js
// NavigationActions is super critical
import { NavigationActions, StackNavigator } from 'react-navigation'
// these are literally whatever you want, standard components
// but, they are sitting in the root of the stack
import Splash from '../components/Auth/Splash'
import SignUp from '../components/Auth/SignupForm'
import SignIn from '../components/Auth/LoginForm'
import ForgottenPassword from '../components/Auth/ForgottenPassword'
// this is an example of a nested view, you might see after logging in
import Dashboard from '../components/Dashboard' // index.js file
const WeLoggedIn = StackNavigator({
LandingPad: { // if you don't specify an initial route,
screen: Dashboard // the first-declared one loads first
}
}, {
headerMode: 'none'
initialRouteName: LandingPad // if you had 5 components in this stack,
}) // this one would load when you do
// this.props.navigation.navigate('WeLoggedIn')
// notice we are exporting this one. this turns into <RootNavigationStack />
// in your src/App.js file.
export const NavigationStack = StackNavigator({
Splash: {
screen: Splash
},
Signup: {
screen: SignUp
},
Login: {
screen: SignIn
},
ForgottenPassword: {
screen: ForgottenPassword
},
WeLoggedIn: {
screen: WeLoggedIn // Notice how the screen is a StackNavigator
} // now you understand how it works!
}, {
headerMode: 'none'
})
// this is super critical for everything playing nice with Redux
// did you read the React-Navigation docs and recall when it said
// most people don't hook it up correctly? well, yours is now correct.
// this is translating your state properly into Redux on initialization
const INITIAL_STATE = NavigationStack.router.getStateForAction(NavigationActions.init())
// this is pretty much a standard reducer, but it looks fancy
// all it cares about is "did the navigation stack change?"
// if yes => update the stack
// if no => pass current stack through
export default (state = INITIAL_STATE, action) => {
const nextState = NavigationStack.router.getStateForAction(action, state)
return nextState || state
}
src / store / index.js
// remember when I said this is just a standard store
// this one is a little more advanced to show you
import { createStore, compose, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { persistStore, autoRehydrate } from 'redux-persist'
import { AsyncStorage } from 'react-native'
// this pulls in your combinedReducers
// nav_reducer is one of them
import reducers from '../reducers'
const store = createStore(
reducers,
{},
compose(
applyMiddleware(thunk),
autoRehydrate()
)
)
persistStore(store, { storage: AsyncStorage, whitelist: [] })
// this exports it for App.js
export default store
src / reducers.js
// here is my reducers file. i don't want any confusion
import { combineReducers } from 'redux'
// this is a standard reducer, same as you've been using since kindergarten
// with action types like LOGIN_SUCCESS, LOGIN_FAIL
import loginReducer from './components/Auth/login_reducer'
import navReducer from './navigation/nav_reducer'
export default combineReducers({
auth: loginReducer,
nav: navReducer
})
src / components / Auth / SignUpForm.js
여기서 샘플을 보여 드리겠습니다. 이건 내 것이 아니에요. 그냥이 잔인한 StackOverflow 편집기에 입력 해 놓았습니다. 감사하면 좋아요 부탁드립니다 :)
import React, { Component } from 'react'
import { View, Text, TouchableOpacity } from 'react-native
// notice how this.props.navigation just works, no mapStateToProps
// some wizards made this, not me
class SignUp extends Component {
render() {
return (
<View>
<Text>Signup</Text>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Login')}>
<Text>Go to Login View</Text>
</TouchableOpacity>
</View>
)
}
}
export default SignUp
src / components / Auth / LoginForm.js
멍청한 스타일도 보여 드릴게요 슈퍼 도프 백 버튼으로
import React from 'react'
import { View, Text, TouchableOpacity } from 'react-native
// notice how we pass navigation in
const SignIn = ({ navigation }) => {
return (
<View>
<Text>Log in</Text>
<TouchableOpacity onPress={() => navigation.goBack(null)}>
<Text>Go back to Sign up View</Text>
</TouchableOpacity>
</View>
)
}
export default SignIn
src / components / Auth / Splash.js
여기에서 놀 수있는 스플래시 화면이 있습니다. 나는 그것을 고차 구성 요소처럼 사용하고 있습니다.
import React, { Component } from 'react'
import { StyleSheet, View, Image, Text } from 'react-native'
// https://github.com/oblador/react-native-animatable
// this is a library you REALLY should be using
import * as Animatable from 'react-native-animatable'
import { connect } from 'react-redux'
import { initializeApp } from './login_actions'
class Splash extends Component {
constructor(props) {
super(props)
this.state = {}
}
componentWillMount() {
setTimeout(() => this.props.initializeApp(), 2000)
}
componentWillReceiveProps(nextProps) {
// if (!nextProps.authenticated) this.props.navigation.navigate('Login')
if (nextProps.authenticated) this.props.navigation.navigate('WeLoggedIn')
}
render() {
const { container, image, text } = styles
return (
<View style={container}>
<Image
style={image}
source={require('./logo.png')}
/>
<Animatable.Text
style={text}
duration={1500}
animation="rubberBand"
easing="linear"
iterationCount="infinite"
>
Loading...
</Animatable.Text>
<Text>{(this.props.authenticated) ? 'LOGGED IN' : 'NOT LOGGED IN'}</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F0F0F0'
},
image: {
height: 110,
resizeMode: 'contain'
},
text: {
marginTop: 50,
fontSize: 15,
color: '#1A1A1A'
}
})
// my LOGIN_SUCCESS action creator flips state.auth.isAuthenticated to true
// so this splash screen just watches it
const mapStateToProps = ({ auth }) => {
return {
authenticated: auth.isAuthenticated
}
}
export default connect(mapStateToProps, { initializeApp })(Splash)
src / components / Auth / login_actions.js
몇 가지 아이디어를 얻을 수 있도록 initializeApp ()을 보여 드리겠습니다.
import {
INITIALIZE_APP,
CHECK_REMEMBER_ME,
TOGGLE_REMEMBER_ME,
LOGIN_INITIALIZE,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT
} from './login_types'
//INITIALIZE APP
// this isn't done, no try/catch and LOGIN_FAIL isn't hooked up
// but you get the idea
// if a valid JWT is detected, they will be navigated to WeLoggedIn
export const initializeApp = () => {
return async (dispatch) => {
dispatch({ type: INITIALIZE_APP })
const user = await AsyncStorage.getItem('token')
.catch((error) => dispatch({ type: LOGIN_FAIL, payload: error }))
if (!user) return dispatch({ type: LOGIN_FAIL, payload: 'No Token' })
return dispatch({
type: LOGIN_SUCCESS,
payload: user
})
// navigation.navigate('WeLoggedIn')
// pass navigation into this function if you want
}
}
다른 사용 사례에서는 고차 구성 요소를 선호 할 수 있습니다. 웹용 React와 똑같이 작동합니다. Udemy에 대한 Stephen Grider의 튜토리얼이 최고입니다.
src / HOC / require_auth.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
export default function (ComposedComponent) {
class Authentication extends Component {
componentWillMount() {
if (!this.props.authenticated) this.props.navigation.navigate('Login')
}
componentWillUpdate(nextProps) {
if (!nextProps.authenticated) this.props.navigation.navigate('Login')
}
render() {
return (
<ComposedComponent {...this.props} />
)
}
}
const mapStateToProps = ({ auth }) => {
return {
authenticated: auth.isAuthenticated
}
}
return connect(mapStateToProps)(Authentication)
}
다음과 같이 사용합니다.
import requireAuth from '../HOC/require_auth'
class RestrictedArea extends Component {
// ... normal view component
}
//map state to props
export default connect(mapStateToProps, actions)(requireAuth(RestrictedArea))
그게 제가 누군가에게 말하고 보여 주었으면하는 모든 것입니다.
TLDR
App.js
, 및nav_reducer.js
파일은 제대로 작동 하는 데 절대적으로 가장 중요합니다. 나머지는 익숙합니다. 내 예는 당신을 야만적 인 생산성 기계로 가속시킬 것입니다.
[편집] 내 로그 아웃 액션 생성자입니다. 사용자가 Android 하드웨어 뒤로 버튼을 누르고 인증이 필요한 화면으로 돌아갈 수 없도록 탐색 스택을 지우려는 경우 매우 유용합니다.
//LOGOUT
export const onLogout = (navigation) => {
return async (dispatch) => {
try {
await AsyncStorage.removeItem('token')
navigation.dispatch({
type: 'Navigation/RESET',
index: 0,
actions: [{ type: 'Navigate', routeName: 'Login' }]
})
return dispatch({ type: LOGOUT })
} catch (errors) {
// pass the user through with no error
// this restores INITIAL_STATE (see login_reducer.js)
return dispatch({ type: LOGOUT })
}
}
}
// login_reducer.js
case LOGOUT: {
return {
...INITIAL_STATE,
isAuthenticated: false,
}
}
[보너스 편집] 하위 스택 네비게이터에서 상위 스택 네비게이터로 어떻게 이동합니까?
하위 스택 네비게이터 중 하나에서 탐색하고 스택을 재설정하려면 다음을 수행하십시오.
this.props.navigation
가능한 경우 코드를 추가하는 구성 요소 내부에 있어야 합니다.- 다음과 같은 구성 요소 만들기
<Something />
- 다음과 같이 탐색을 전달하십시오.
<Something navigation={this.props.navigation} />
- 해당 구성 요소의 코드로 이동
this.props.navigation
이 하위 구성 요소 내에서 어떻게 사용할 수 있는지 확인하십시오.- 이제 끝났습니다. 전화 만하면
this.props.navigation.navigate('OtherStackScreen')
React Native가 마법처럼 문제없이 이동하는 것을 볼 수 있습니다.
그러나 부모 스택으로 이동하는 동안 전체 스택 을 재설정하고 싶습니다 .
- 액션 생성 자나 다음과 같은 것을 호출합니다 (6 단계부터 시작).
this.props.handleSubmit(data, this.props.navigation)
- 액션 생성자로 가서 거기에있을 수있는 다음 코드를 관찰하십시오.
actionCreators.js
// we need this to properly go from child to parent navigator while resetting
// if you do the normal reset method from a child navigator:
this.props.navigation.dispatch({
type: 'Navigation/RESET',
index: 0,
actions: [{ type: 'Navigate', routeName: 'SomeRootScreen' }]
})
// you will see an error about big red error message and
// screen must be in your current stack
// don't worry, I got your back. do this
// (remember, this is in the context of an action creator):
import { NavigationActions } from 'react-navigation'
// notice how we passed in this.props.navigation from the component,
// so we can just call it like Dan Abramov mixed with Gandolf
export const handleSubmit = (token, navigation) => async (dispatch) => {
try {
// lets do some operation with the token
await AsyncStorage.setItem('token@E1', token)
// let's dispatch some action that doesn't itself cause navigation
// if you get into trouble, investigate shouldComponentUpdate()
// and make it return false if it detects this action at this moment
dispatch({ type: SOMETHING_COMPLETE })
// heres where it gets 100% crazy and exhilarating
return navigation.dispatch(NavigationActions.reset({
// this says put it on index 0, aka top of stack
index: 0,
// this key: null is 9001% critical, this is what
// actually wipes the stack
key: null,
// this navigates you to some screen that is in the Root Navigation Stack
actions: [NavigationActions.navigate({ routeName: 'SomeRootScreen' })]
}))
} catch (error) {
dispatch({ type: SOMETHING_COMPLETE })
// User should login manually if token fails to save
return navigation.dispatch(NavigationActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: 'Login' })]
}))
}
}
엔터프라이즈 급 React Native 앱 내에서이 코드를 사용하고 있으며 아름답게 작동합니다.
react-navigation
함수형 프로그래밍과 같습니다. 함께 잘 구성되는 작은 "순수 탐색"조각으로 처리되도록 설계되었습니다. 위에서 설명한 전략을 사용하면 필요에 따라 붙여 넣을 수있는 재사용 가능한 탐색 논리를 만들 수 있습니다.
Manjeet이 제안한 것이 효과가 있지만 좋은 항해 구조는 아닙니다.
당신이해야 할 일은 한 발 물러서서 다른 수준에서 모든 것을 처리하는 것입니다.
최상위 네비게이터는 로그인 화면을 렌더링하는 스택 네비게이터 여야합니다. 이 최상위 네비게이터 내의 또 다른 화면은 앱의 메인 네비게이터 여야합니다. 로그인 상태가 만족되면 메인 스택을 메인 네비게이터로 재설정합니다.
이 구조의 이유는 다음과 같습니다.
A- 나중에 로그인하기 전에 온 보딩 정보를 추가해야하는 경우 어떻게합니까?
B- 기본 탐색 환경 외부에서 탐색해야하는 경우 (예 : 기본 탐색이 탭이고 탭이 아닌보기를 원함)?
최상위 네비게이터가 로그인 화면 및 기타 네비게이터를 표시하는 Stack-Navigator 인 경우 앱의 탐색 구조를 적절하게 확장 할 수 있습니다.
위에서 제안한 것처럼 로그인 화면이나 스택 네비게이터의 조건부 렌더링이 좋은 생각이라고 생각하지 않습니다 .... 저를 믿으세요 ... 저는 그 길을 따라갔습니다.
이것이 제가이 기능을 달성 한 방법입니다.
파일 0) index.android.js
'use strict'
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import Root from 'src/containers/Root'
AppRegistry.registerComponent('Riduk', () => Root);
파일 1) my Root.js
class Root extends Component {
constructor(props) {
super(props);
this.state = {
authenticated:false,
isLoading:true,
store: configureStore(() => this.setState({isLoading: false})),
};
}
componentDidMount() {
//you can do check with authentication with fb, gmail and other right here
/* firebase.auth().onAuthStateChanged((user) => {
if (user) {
api.resetRouteStack(dispatch, "UserProfile");
console.log("authenticated", user);
} else {
api.resetRouteStack(dispatch, "Landing");
console.log("authenticated", false);
}
});*/
}
render() {
if (this.state.isLoading) { //checking if the app fully loaded or not, splash screen can be rendered here
return null;
}
return (
<Provider store={this.state.store}>
<App/>
</Provider>
);
}
}
module.exports = Root;
2) App.js
import AppWithNavigationState,{AppBeforeLogin} from './AppNavigator';
class App extends Component{
constructor(props){
super(props);
}
render(){
let {authenticated} = this.props;
if(authenticated){
return <AppWithNavigationState/>;
}
return <AppBeforeLogin/>
}
}
export default connect(state =>({authenticated: state.user.authenticated}))(App);
3) AppNavigator.js
'use strict';
import React, {Component} from 'react';
import { View, BackAndroid, StatusBar,} from 'react-native';
import {
NavigationActions,
addNavigationHelpers,
StackNavigator,
} from 'react-navigation';
import { connect} from 'react-redux';
import LandingScreen from 'src/screens/landingScreen';
import Login from 'src/screens/login'
import SignUp from 'src/screens/signUp'
import ForgotPassword from 'src/screens/forgotPassword'
import UserProfile from 'src/screens/userProfile'
import Drawer from 'src/screens/drawer'
const routesConfig = {
//Splash:{screen:SplashScreen},
Landing:{screen:LandingScreen},
Login: { screen: Login },
SignUp: { screen: SignUp },
ForgotPassword: { screen: ForgotPassword },
UserProfile:{screen:UserProfile},
};
export const AppNavigator = StackNavigator(routesConfig, {initialRouteName:'UserProfile'}); //navigator that will be used after login
export const AppBeforeLogin = StackNavigator (routesConfig); // 로그인 전의 naviagtor
class AppWithNavigationState extends Component{
constructor(props) {
super(props);
this.handleBackButton = this.handleBackButton.bind(this);
}
componentDidMount() {
BackAndroid.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackAndroid.removeEventListener('hardwareBackPress', this.handleBackButton);
}
//added to handle back button functionality on android
handleBackButton() {
const {nav, dispatch} = this.props;
if (nav && nav.routes && nav.routes.length > 1) {
dispatch(NavigationActions.back());
return true;
}
return false;
}
render() {
let {dispatch, nav} = this.props;
return (
<View style={styles.container}>
{(api.isAndroid()) &&
<StatusBar
backgroundColor="#C2185B"
barStyle="light-content"
/>
}
<AppNavigator navigation={addNavigationHelpers({ dispatch, state: nav })}/>
</View>
);
}
};
export default connect(state =>({nav: state.nav}))(AppWithNavigationState);
//module.exports = AppWithNavigationState;
이것은 @parker 권장 사항을 기반으로 한 내 솔루션입니다 .
- 최상위 네비게이터를 만들고 로그인 화면을 렌더링하는 스택 네비게이터 여야합니다.
- 이 최상위 네비게이터 내의 다른 화면은 앱의 메인 네비게이터 여야합니다.
- 로그인 상태가 만족되면 메인 스택을 메인 네비게이터로 재설정합니다.
이 코드는 위의 작업을 수행하기 위해 최소한의 작업을 수행합니다.
새 반응 네이티브 프로젝트를 만든 다음 아래 코드를 index.ios.js 및 / 또는 index.android.js에 복사하여 작동하는지 확인합니다.
import React, { Component } from 'react';
import {
AppRegistry,
Text,
Button
} from 'react-native';
import { StackNavigator, NavigationActions } from 'react-navigation';
const resetAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'Main' })
]
});
class LoginScreen extends Component {
login() {
this.props.navigation.dispatch(resetAction);
}
render() {
return <Button title='Login' onPress={() => {this.login()}} />;
}
}
class FeedScreen extends Component {
render() {
return <Text>This is my main app screen after login</Text>;
}
}
//Create the navigation
const MainNav = StackNavigator({
Feed: { screen: FeedScreen },
});
const TopLevelNav = StackNavigator({
Login: { screen: LoginScreen },
Main: { screen: MainNav },
}, {
headerMode: 'none',
});
AppRegistry.registerComponent('ReactNav2', () => TopLevelNav);
앱에 필요한 대부분의 기능을 잘 지원하는 react-navigation을 사용하는 것이 좋습니다. 여기 내 충고
1) 인증시
React-native에는 변경된 뷰가 다시 렌더링되는 멋진 기능 상태 변수 가 있습니다. 상태 변수를 사용하여 앱 사용자의 "상태"(인증 됨 / 방문자)를 이해할 수 있습니다.
다음은 사용자가 로그인 버튼을 눌러 로그인하는 간단한 구현입니다.
사용자가 로그인하는 시작 페이지
import React from 'react';
import Home from './layouts/users/home/Home';
import Login from './layouts/public/login/Login';
class App extends React.Component {
state = {
isLoggedIn: false
}
componentDidMount() {
//Do something here like hide splash screen
}
render(){
if (this.state.isLoggedIn)
return <Home
/>;
else
return <Login
onLoginPress={() => this.setState({isLoggedIn: true})}
/>;
}
}
export default App;
2) 헤더로 로그인
로그인보기
import React from 'react';
//Non react-native import
import { TabNavigator } from 'react-navigation'
import Icon from 'react-native-vector-icons/MaterialIcons'
import LoginStyles from './Style'
//Do all imports found in react-native here
import {
View,
Text,
TextInput,
StyleSheet,
TouchableOpacity,
} from 'react-native';
class Login extends React.Component {
render(){
return (
<View>
<Text>
Login area
</Text>
<TouchableOpacity
style={LoginStyles.touchable}
onPress={this.props.onLoginPress} >
<Text style={LoginStyles.button}>
Login
</Text>
</TouchableOpacity>
</View>
);
}
}
export default Login;
로그인 화면에서 스타일 속성을 제거하고 가져 오기를 포함하여 귀하의 속성을 추가하는 것을 잊지 마십시오. 프로젝트에 반응 할 수있는 방법을 알고있는 데 도움이 될 수 있으므로 그대로 둡니다.
그러나 스타일 없이도 작동하므로 스타일을 벗을 수 있습니다. 로그인 버튼을 클릭하면 상태가 변경되고 새 상태에 따라 뷰를 다시 렌더링해야하기 때문에 홈 화면으로 이동합니다.
로그인 화면에는 필요에 따라 헤더가 없습니다.
탭이있는 홈 화면
3) 헤더가 있는 탭 이 기능을 달성하는 일반적인 방법 TabNavigator
은 StackNavigator
.
import React from 'react';
import {
DrawerNavigator,
StackNavigator,
TabNavigator,
TabBarBottom,
NavigationActions
} from 'react-navigation'
import Icon from 'react-native-vector-icons/MaterialIcons'
//Do all imports found in react-native here
import {
View,
Text,
TextInput,
StyleSheet,
TouchableOpacity,
} from 'react-native';
class PicturesTab extends React.Component {
static navigationOptions = {
tabBarLabel: 'Pictures',
// Note: By default the icon is only shown on iOS. Search the showIcon option below.
tabBarIcon: ({ tintColor }) => (<Icon size={30} color={tintColor} name="photo" />),
};
render() { return <Text>Pictures</Text> }
}
class VideosTab extends React.Component {
static navigationOptions = {
tabBarLabel: 'Videos',
tabBarIcon: ({ tintColor }) => (<Icon size={30} color={tintColor} name="videocam" />),
};
render() { return <Text>Videos</Text> }
}
const HomeTabs = TabNavigator({
Pictures: {
screen: PicturesTab,
},
Videos: {
screen: VideosTab,
},
}, {
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
tabBarOptions: {
//Thick teal #094545
activeTintColor: '#094545',
showLabel: false,
activeBackgroundColor: '#094545',
inactiveTintColor: '#bbb',
activeTintColor: '#fff',
}
});
const HomeScreen = StackNavigator({
HomeTabs : { screen: HomeTabs,
navigationOptions: ({ navigation }) => ({
// title :'title',
// headerRight:'put some component here',
// headerLeft:'put some component here',
headerStyle: {
backgroundColor: '#094545'
}
})
},
});
export default HomeScreen;
면책 조항 : 일부 파일이 누락되거나 일부 오타가있을 수 있으므로 코드에서 오류를 반환 할 수 있습니다. 세부 정보를주의 깊게 확인하고이 코드를 복사해야하는 경우 필요한 위치를 변경해야합니다. 모든 문제는 주석으로 붙여 넣을 수 있습니다. 이것이 누군가를 돕기를 바랍니다.
탭 구성에서 아이콘을 제거하거나 탭을 멋지게 만드는 react-native-vector 아이콘을 설치할 수도 있습니다!
react-navigation
이제 SwitchNavigator
원하는 동작과 네비게이터 간 전환에 도움이되는가 있습니다. 현재 이에 대한 문서는 많지 않지만 간단한 인증 흐름 구현을 보여주는 라이브러리에서 만든 정말 좋은 예제 스낵이 있습니다. 여기에서 확인할 수 있습니다 .
SwitchNavigator 참조
SwitchNavigator(RouteConfigs, SwitchNavigatorConfig)
문서의 예
const AppStack = StackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = StackNavigator({ SignIn: SignInScreen });
export default SwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: AppStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
);
탭 바와 헤더를 별도의 구성 요소로 만들고 다른 구성 요소에만 포함하십시오. "뒤로"비활성화에 대한 문서에는 "탐색 작업 차단"에 대한 섹션이 있습니다. https://reactnavigation.org/docs/routers/
화면 2에서 사용할 수 있어야합니다.
이제 react-navigation 사이트 에 인증 흐름에 대한 좋은 문서가 있습니다 .
나는 내가 여기서 늙었다는 것을 알고 있지만,이 기사는 내 엉덩이를 구했고, 나는 내비게이션으로 지옥에 있으며, 이제는 더 편하게 느껴진다.
그 사람은 메인 스택 네비게이터를 사용하여 당신이 상상하는대로 정확하게 네비게이션을 구축 할 수있게 해주는 내부 API를 설명하고 있습니다.
인증 예제로 깊이 들어가
이 녀석을 박수주세요 :-)
LIST 페이지에서 LOGIN 페이지로 돌아가는 버튼을 원하지 않으면 다음과 같이 할 수 있습니다.
static navigationOptions = {
title: 'YOUR TITLE',
headerLeft : null,
};
I needed this, but none of the other solutions worked for me. So here is my solution for a Login with a drawer (the latter accessible only after proper authentication, and each of the screens inside have there own navigation stack). My code has a DrawerNavigator, but the same could be used for a TabNavigator (createBottomTabNavigator).
wrapScreen = stackNavigator =>
createStackNavigator(stackNavigator, {
defaultNavigationOptions: ({ navigation }) => ({
headerStyle: { backgroundColor: "white" },
headerLeft: MenuButton(navigation)
})
});
const DrawerStack = createDrawerNavigator(
{
// Menu Screens
firstSection: wrapScreen({ FirstScreen: FirstScreen }),
secondSection: wrapScreen({
SecondHomeScreen: SecondHomeScreen,
SecondOptionScreen: SecondOptionScreen
}),
settingSection: wrapScreen({ SettingScreen: SettingScreen }),
aboutSection: wrapScreen({ AboutScreen: AboutScreen })
},
{
initialRouteName: "firstSection",
gesturesEnabled: false,
drawerPosition: "left",
contentComponent: DrawerContainer
}
);
const PrimaryNav = createSwitchNavigator(
{
loginStack: LoginScreen,
appStack: DrawerStack
},
{ initialRouteName: "loginStack" }
);
export default createAppContainer(PrimaryNav);
I hope it can help others.
참고URL : https://stackoverflow.com/questions/42876690/react-navigation-with-login-screen
'program tip' 카테고리의 다른 글
이 Android SDK에는 Android Developer Toolkit 버전 23.0.0 이상이 필요합니다. (0) | 2020.12.08 |
---|---|
AngularJS-ng-disabled가 앵커 태그에 대해 작동하지 않음 (0) | 2020.12.08 |
블레이드에서 Laravel .env 변수에 액세스 (0) | 2020.12.08 |
Objective C 메시지 디스패치 메커니즘 (0) | 2020.12.08 |
이것이 null인지 확인 (0) | 2020.12.08 |