2016-08-09 42 views
2

我想用終極版爲本地做出反應。目前我沒有設置數據管理,所以index.ios.js有以下內容:React Native + Redux:什麼是最好的和首選的導航?

renderScene(route, navigator){ 
    this._navigator = navigator 

    return (
     <route.component navigator={navigator} {...route.passProps}/> 
    ) 
    } 

<Navigator 
    configureScene={this.configureScene} 
    initialRoute={{name: 'Login', component: Login}} 
    renderScene={(route, navigator) => this.renderScene(route, navigator)} 
    style={styles.container} 
    navigationBar={ 
    <Navigator.NavigationBar 
     style={styles.navBar} 
     routeMapper={NavigationBarRouteMapper} 
    /> 
    } 
/> 

我打算切換到Redux。使用我目前的設置,不使用任何框架,只有例外是react-router,使用Redux進行導航的最佳方式是什麼?使用商店,縮減者和操作的示例將非常有用。

+1

你應該看看支持reducer的NavigatorExperimental。現有導航器正在折舊。 https://medium.com/@dabit3/first-look-react-native-navigator-experimental-9a7cf39a615b – while1

回答

5

編輯:反應導航現在應該用來代替NavigationExperimental。

-

我建議您使用NavigationExperimental而不是Navigator。最後一個折舊。 RN文檔中有一個示例,right here。它使用簡單的減速器來管理您的導航狀態。但是你也可以用Redux處理這個狀態,因爲它是相同的邏輯。

這是我的設置與標籤,使用終極版和NavigationExperimental:

navigator.js(注:在CardStack的renderOverlay道具將在0.32改名renderHeader)

import React from 'react'; 
import { NavigationExperimental } from 'react-native'; 
import { connect } from 'react-redux'; 
import { pop, push, selectTab } from './actions'; 

const { 
    CardStack: NavigationCardStack, 
} = NavigationExperimental; 

class Navigator extends React.Component { 
    constructor(props) { 
    super(props); 
    this._renderHeader = this._renderHeader.bind(this); 
    this._renderScene = this._renderScene.bind(this); 
    } 

    _renderHeader(sceneProps) { 
    return (
     <MyHeader 
     {...sceneProps} 
     navigate={this.props.navigate} 
     /> 
    ); 
    } 

    _renderScene(sceneProps) { 
    return (
     <MyScene 
     {...sceneProps} 
     navigate={this.props.navigate} 
     /> 
    ); 
    } 

    render() { 
    const { appNavigationState: { scenes, tabKey, tabs } } = this.props; 

    return (
     <View style={{ flex: 1 }}> 
     <NavigationCardStack 
      key={`stack_${tabKey}`} 
      navigationState={scenes} 
      renderOverlay={this._renderHeader} 
      renderScene={this._renderScene} 
     /> 
     <Tabs 
      navigationState={tabs} 
      navigate={this.props.navigate} 
     /> 
     </View> 
    ); 
    } 
} 

const getCurrentNavigation = (navigation) => { 
    const tabs = navigation.tabs; 
    const tabKey = tabs.routes[tabs.index].key; 
    const scenes = navigation[tabKey]; 
    return { 
    scenes, 
    tabKey, 
    tabs, 
    }; 
}; 

const mapStateToProps = (state) => { 
    return { 
    appNavigationState: getCurrentNavigation(state.navigation), 
    }; 
}; 

const mapDispatchToProps = (dispatch) => { 
    return { 
    navigate: (action) => { 
     if (action.type === 'pop') { 
     dispatch(pop()); 
     } else if (action.type === 'push' && action.route) { 
     dispatch(push(action.route)); 
     } else if (action.type === 'tab' && action.tabKey) { 
     dispatch(selectTab(action.tabKey)); 
     } 
    } 
    }; 
}; 

export default connect(
    mapStateToProps, 
    mapDispatchToProps, 
)(Navigator); 

actions.js

export function pop() { 
    return ({ 
    type: 'POP_ROUTE', 
    }); 
} 

export function push(route) { 
    return ({ 
    type: 'PUSH_ROUTE', 
    route, 
    }); 
} 

export function selectTab(tabKey) { 
    return ({ 
    type: 'SELECT_TAB', 
    tabKey, 
    }); 
} 

reducer.js(注:我在這裏一成不變的使用,但它是由你來使用任何適合你

import { NavigationExperimental } from 'react-native'; 
import { Record } from 'immutable'; 

const { 
    StateUtils: NavigationStateUtils, 
} = NavigationExperimental; 


export const InitialState = Record({ 
    // Tabs 
    tabs: { 
    index: 0, 
    routes: [ 
     { key: 'tab1' }, 
     { key: 'tab2' }, 
     { key: 'tab3' }, 
    ], 
    }, 
    // Scenes 
    tab1: { 
    index: 0, 
    routes: [{ key: 'tab1' }], 
    }, 
    tab2: { 
    index: 0, 
    routes: [{ key: 'tab2' }], 
    }, 
    tab3: { 
    index: 0, 
    routes: [{ key: 'tab3' }], 
    }, 
}); 
const initialState = new InitialState(); 


export default function navigation(state = initialState, action) { 
    switch (action.type) { 
    case 'POP_ROUTE': { 
     const tabs = state.get('tabs'); 
     const tabKey = tabs.routes[tabs.index].key; 
     const scenes = state.get(tabKey); 
     const nextScenes = NavigationStateUtils.pop(scenes); 

     if (scenes !== nextScenes) { 
     return state.set(tabKey, nextScenes); 
     } 
     return state; 
    } 

    case 'PUSH_ROUTE': { 
     const route = action.route; 
     const tabs = state.get('tabs'); 
     const tabKey = tabs.routes[tabs.index].key; 
     const scenes = state.get(tabKey); 
     const nextScenes = NavigationStateUtils.push(scenes, route); 

     if (scenes !== nextScenes) { 
     return state.set(tabKey, nextScenes); 
     } 
     return state; 
    } 

    case 'SELECT_TAB': { 
     const tabKey = action.tabKey; 
     const tabs = state.get('tabs'); 
     const nextTabs = NavigationStateUtils.jumpTo(tabs, tabKey); 

     if (nextTabs !== tabs) { 
     return state.set('tabs', nextTabs); 
     } 
     return state; 
    } 

    default: 
     return state; 
    } 
} 

最後,在MyScene.js組件,您可以簡單地處理組件通過測試當前路線來顯示(例如用開關)。 通過傳遞導航功能在您的組件,您可以管理您的場景(即:this.props.navigate({類型:「推」,路線:{鍵:「搜索」}}))。

通知,如你所願,你可以處理你的狀態,你的行動。要理解的主要想法是如何減少狀態,無論是否使用減少或減少。

+0

真的很感激它!但我期待實現一個導航條。那麼我應該怎麼做,我該怎麼辦?隨着後退按鈕等事先謝謝你Yupichaks! –

+0

我也必須單獨定義每條路線,或者我可以執行以下操作:''? –

+0

我的示例中的_MyHeader_組件是導航欄。 NavigationExperimental包括標題和標題組件:) [見此要點](https://gist.github.com/yspychala/f6d685751abca41c6dc291d5333c97a1) 關於你的第二個問題,我沒有這樣測試。你應該嘗試看看最適合你的是什麼。 – Yupichaks

2

我建議你使用react-navigation原生和網絡環境它將replace NavigationExperimental只是看看下面的example

  • 組件適用於移動應用,Web應用程序和服務器之間呈現iOS和Android
  • 分享導航邏輯建成。
  • Documentation是非常簡單的
  • 開發自己navigation views
  • 這是很容易!

只需在您的應用中定義您的導航。

import { 
    TabNavigator, 
} from 'react-navigation'; 

const BasicApp = TabNavigator({ 
    Main: {screen: MainScreen}, 
    Setup: {screen: SetupScreen}, 
}); 

...並找到

class MainScreen extends React.Component { 
    static navigationOptions = { 
    label: 'Home', 
    }; 
    render() { 
    const { navigate } = this.props.navigation; 
    return (
     <Button 
     title="Go to Setup Tab" 
     onPress={() => navigate('Setup')} 
     /> 
    ); 
    } 
} 

並執行以下操作以添加redux只是定義你的減速...

const AppNavigator = StackNavigator(AppRouteConfigs); 

const appReducer = combineReducers({ 
    nav: (state, action) => (
    AppNavigator.router.getStateForAction(action, state) 
) 
}); 

...並找到在你的組件與addNavigationHelpers

<AppNavigator navigation={addNavigationHelpers({ 
    dispatch: this.props.dispatch, 
    state: this.props.nav, 
    })} /> 
相關問題