React-native导航实验示例?

时间:2016-04-21 02:28:16

标签: navigation react-native flux reactjs-flux react-redux

几周前我开始使用 react-native 。对于我的第一个应用,我使用导航器进行导航,其导航栏组件显示标题和左/右侧按钮。阅读 facebook已经放弃了对导航器的支持并开发了n avigation experimental或navigation-rfc 将调用' NavExp '缩短),我正在尝试使用NavExp。但我无法理解它。

应用程序菜单:适用于Android的DrawerLayout,适用于IOS的TabIOS。并且将根据内容使用导航栏显示标题和右侧(内容特定菜单 - 打印,复制)/左(用于菜单)按钮。

  1. navigator与NavExp有什么区别? (它说它提供redux或flux风格导航,也无法理解)
  2. reducer的目的是什么?(使用哪一个?(Stack,Find))
  3. NavigationRootContainer?
  4. 在哪里宣布我的所有州,因为这些是常数?
  5. 行动与州之间有什么区别?
  6. 对于导航器,我们使用renderScene函数实际渲染场景,在NavExp中

2 个答案:

答案 0 :(得分:7)

在一个SO问题中打开很多东西,所以通过做一些研究然后将这个问题分成几个小问题,你可能会得到更好的服务。这里有一些指导可以帮助你入门。

总体来说:新NavigationExperimental的目的是为React Native创建无状态导航结构,遵循与React相同的原则。与新的NavExp相比,旧的Navigator组件更依赖于维护和变异状态。如果您考虑React如何喜欢采用一组道具,然后在某些内容发生变化时渲染出全新的UI,那么新的NavExp旨在为此提供更多便利。

这是因为当您使用类似Flux的模式来管理应用程序中的状态时更有用。我建议阅读Flux,或者在我看来,更容易掌握Redux模式的实现。

这回答了#1的范围,并且在通过这些链接之后,您将更好地理解#2的答案。

  1. NavigationRootContainer是一个有用的元素(虽然不是必需的),它在使用NavExp时提供了一些结构和功能。 Facebook的例子使用它。如果您使用Redux之类的东西实现NavExp,则不需要使用它,因为您将复制reducers的使用。

  2. 我假设您在决定渲染适当的场景/卡片/屏幕时谈论状态?这些可以在任何地方声明,而且实际上只是字符串。你甚至不需要在任何地方申报。

  3. State是组成应用程序移动部分的数据和变量的集合。例如,如果您有一个购物车应用程序,您可以将客户的名称和购物车内容存储在您的应用程序状态,以及他们当前所在的屏幕,他们之前的屏幕任何可以改变的东西都在状态。

  4. 行动就像向空中射击,以提醒应用程序的其他部分发生了变化。用户是否在购物车中添加了新商品?发送ITEM_ADDED_TO_CART操作以及项目的ID。用户按下主屏幕按钮?发送NAVIGATE_TO_SCREEN操作以及主屏幕的标识符。 reduce由reducers处理,reducers对状态进行更改,然后告诉React Native开始重新渲染所有内容。

    1. 这并没有形成一个问题,但你有一个renderScene方法也使用NavExp,它以几乎相同的方式运作:它吐出屏幕的内容,无论它应该是什么
    2. (仅供参考,我对此没有任何官方消息,但如果您已经熟悉Navigator并已实施它,那么在可预见的未来,您可能会继续使用它,而不是重写您的应用程序可以利用NavigationExperimental。)

答案 1 :(得分:2)

基于此处的评论,您应该使用NavigationExpermiental: https://github.com/facebook/react-native/issues/6184

这是一个很好的例子来帮助你入门: https://github.com/thebakeryio/react-native-complex-nav

import { View, NavigationExperimental } from 'react-native';
import React, { Component } from 'react';
import styles from './styles';
import { connect } from 'react-redux';
import ApplicationTabs from '../ApplicationTabs';
import NewItem from '../NewItem';
const { CardStack: NavigationCardStack } = NavigationExperimental;

class GlobalNavigation extends Component {
    render() {
        return (
            <NavigationCardStack
                direction={'vertical'}
                navigationState={this.props.navigation}
                onNavigate={this.props.onNavigate}
                renderScene={this._renderScene.bind(this)}
                renderOverlay={this._renderHeader.bind(this)}
                style={styles.main}
            />
        );
    }

    _renderHeader(props) {
        return null;
    }

    _renderScene(props) {
        if (props.scene.navigationState.key === 'applicationTabs') {
            return (
                <View style={{flex: 1}}>
                    <ApplicationTabs />
                </View>
            );
        }

        if (props.scene.navigationState.key === 'new') {
            return (
                <View style={{flex: 1}}>
                    <NewItem onClose={this._onCloseNewItem.bind(this)} />
                </View>
            );
        }
    }

    _renderTitleComponent(props) {
        return null;
    }

    _onCloseNewItem() {
        this.props.onNavigate({
            type: 'BackAction'
        });
    }
}

function mapDispatchToProps(dispatch) {
    return {
        dispatch
    };
}

function mapStateToProps(state) {
    return {
        navigation: state.get('globalNavigation')
    };
}

export default connect(mapStateToProps, mapDispatchToProps, (stateProps, dispatchProps, ownProps) => {
    return Object.assign({}, dispatchProps, stateProps, {
        onNavigate: (action) => {
            dispatchProps.dispatch(
                Object.assign(action, {
                    scope: stateProps.navigation.key
                })
            );
        }
    });
})(GlobalNavigation);