2016-08-09 18 views
2

Ich möchte Redux für React Native verwenden. Zur Zeit habe ich kein festes Datenmanagement, so dass der index.ios.js hat die folgenden:React Native + Redux: Was ist die beste und bevorzugte Navigation?

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} 
    /> 
    } 
/> 

ich Redux wechseln bin die Planung. Mit meiner derzeitigen Einrichtung, die keine Frameworks verwendet, nur die Ausnahme, die react-router ist, was wäre der am meisten bevorzugte Weg, um mit Redux zu navigieren? Ein Beispiel mit Speichern, Reduzierungen und Aktionen wäre sehr hilfreich.

+1

Sie sollten in NavigatorExperimental schauen, welche Reduzierer unterstützen. Der vorhandene Navigator wird abgeschrieben. https://medium.com/@dabit3/first-look-react-native-navigator-experimental-9a7cf39a615b – while1

Antwort

5

EDIT: react-navigation sollte nun anstelle von NavigationExperimental verwendet werden.

-

Ich rate Ihnen, verwenden NavigationExperimental statt Navigator. Die letzte wird abgeschrieben. Es gibt ein Beispiel in der RN-Dokumentation, right here. Es verwendet einfache Reduzierungen, um Ihren Navigationsstatus zu verwalten. Aber Sie können diesen Zustand auch mit Redux behandeln, da es dieselbe Logik ist.

Das ist mein Setup mit Tabs, mit Redux und NavigationExperimental:

navigator.js (Anmerkung: die renderOverlay Stütze in CardStack wird renderHeader in 0.32 umbenannt)

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); 

action.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 (Anmerkung: Ich unveränderlich verwenden hier, aber es ist an Ihnen, was passen Sie verwenden) Komponente

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; 
    } 
} 

in MyScene.js Schließlich können Sie einfach die Komponenten-Griff um die aktuelle Route zu testen (zB mit einem Schalter). Durch die Navigation Funktion in Ihren Komponenten können Sie Ihre Szenen verwalten (zB: this.props.navigate ({type: 'push', route: {key: 'search'}})).

Beachten Sie, dass Sie mit Ihrem Status und Ihren Aktionen so umgehen können, wie Sie es wünschen. Die Grundidee zu verstehen ist, wie der Zustand reduziert wird, unabhängig davon, ob Sie redux verwenden oder nicht.

+0

Wirklich zu schätzen wissen! Aber ich suche eine Navigationsleiste zu implementieren. Also, wo soll ich das machen und wie kann ich? Mit dem Zurück-Knopf usw. Vielen Dank im Voraus Yupichaks! –

+0

Muss ich auch jede Route einzeln definieren oder könnte ich so etwas wie folgt machen: ''? –

+0

Die Komponente _MyHeader_ in meinem Beispiel ist die Navigationsleiste. NavigationExperimental enthält eine Header- und eine Title-Komponente :) [Siehe diesen Artikel] (https://gist.github.com/yspychala/f6d685751abca41c6dc291d5333c97a1) Über Ihre zweite Frage habe ich diesen Weg nicht getestet. Sie sollten versuchen zu sehen, was Ihnen am besten passt. – Yupichaks

2

Ich schlage vor, Sie react-navigation für native und Web-Umgebung verwenden, wird es replace NavigationExperimental nur die folgenden example aussehen zu nehmen.

  • für iOS und Android gebaut Komponenten
  • Teile Navigationslogik zwischen mobilen Anwendungen, Web-Anwendungen und Server-Rendering.
  • Documentation ist ziemlich einfach
  • Entwickeln Sie Ihre eigenen navigation views
  • Es ist ganz einfach!

Definieren Sie einfach Ihre Navigation in Ihrer App.

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

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

... und

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')} 
     /> 
    ); 
    } 
} 

navigieren und das folgende tun, um redux fügen Sie einfach Ihre Minderer definieren ...

const AppNavigator = StackNavigator(AppRouteConfigs); 

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

... und in der Komponente navigieren mit addNavigationHelpers

<AppNavigator navigation={addNavigationHelpers({ 
    dispatch: this.props.dispatch, 
    state: this.props.nav, 
    })} /> 
Verwandte Themen