首页 文章

React Native Redux:什么是最好的和首选的导航?

提问于
浏览
2

我想将Redux用于React Native . 目前我没有设置数据管理,因此index.ios.js具有以下内容:

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导航的最佳方式是什么?使用存储,缩减器和操作的示例将非常有用 .

2 回答

  • 2

    我建议你使用react-navigation本地和网络环境它将replace NavigationExperimental看看下面的example .

    • 为iOS和Android构建的组件

    • 在移动应用程序,Web应用程序和服务器呈现之间共享导航逻辑 .

    • 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,
      })} />
    
  • 5

    编辑:现在应该使用react-navigation而不是NavigationExperimental .

    我建议您使用NavigationExperimental而不是Navigator . 最后一个是折旧的 . RN文档中有一个例子,right here . 它使用简单的减速器来管理您的导航状态 . 但是你也可以使用Redux处理这个状态,因为它是相同的逻辑 .

    This is my setup with tabs, using Redux and NavigationExperimental:

    navigator.js(注意:CardStack中的renderOverlay prop将在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( note: I use immutable here, but it's up to you to use whatever fit you

    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({type:'push',route:{key:'search'}})) .

    请注意,您可以根据需要处理您的州和您的行为 . 理解的主要思想是如何减少状态,无论你是否使用redux .

相关问题