• 首先, 现在看一下react navigation官网goBack的描述: goBack的参数为页面的key, 这个key是系统随机分配的, 而不是手动设置的routeName, 所以参数填routeName无法跳转, goBack如果不带参数(即key为undefined)...

    goBack

    首先, 现在看一下react navigation官网中对goBack的描述:
    这里写图片描述

    goBack的参数为页面的key, 这个key是系统随机分配的, 而不是手动设置的routeName, 所以参数填routeName无法跳转, goBack如果不带参数(即key为undefined)会返回上一个页面, 这个参数key不是目标页面的key, 而是可以在key为undefined时goBack到目标页面的那个页面的key. 如果key为null, 那么会回到任何地方.

    可以结合下面链接中的Answer理解:
    https://stackoverflow.com/questions/45489343/react-navigation-back-and-goback-not-working

    如果有 A -> B -> C -> D 四个页面,
    如果想从D回到B, 在react navigation不集成Redux的情况下, 需要在C通过this.props.navigation.state.key 拿到C的key, 然后把C的key传入到D中, 然后在D中执行this.props.navigation.goBack("C页面的key")就可回到B页面.

    显然这样不太方便, 所以最好将Redux集成到react navigation中(react navigaiton官网中有集成方法,在这我就不赘述了).
    集成了redux后, 可以在connect中拿到所有加载过的页面的route, 如:

    class ResetPassword extends Component {
        ...
        render() {
            const { routes } = this.props;
            console.log(routes);
            return (
                ...
            )
        }
    }
    
    export default connect (
        (state) => ({
            routes: state.nav.routes
        })
    )(ResetPassword)

    为什么不使用navigate返回?

    使用navigate()方法返回页面会使StackNavigator的结构乱掉, 导致跳转到目标页面后, 对页面组件的重新渲染会出问题.

    展开全文
  • 写在前面:在ReactNative中,常常会有下面这样的需求。就是像登录一样,登陆成功,我需要做很多事情,存储用户信息、把别的页面(或上一级页面)存在的头像昵称给显示出来。有可能还需要修改离登录页有两个层级页面...

    写在前面:在ReactNative中,常常会有下面这样的需求。就是像登录一样,登陆成功,我需要做很多事情,存储用户信息、把别的页面(或上一级页面)存在的头像昵称给显示出来。有可能还需要修改离登录页有两个层级页面上的数据。基于我现在使用的ReactNative0.51.0版本和react-navigtion1.5.+版本。虽然可以修改navigtion的goBack方法来回参。但是层级一深,将变得难以处理。所以建议使用优秀的框架来处理这种业务逻辑。在这里我选用的是Redux。

    先说一下我所使用的库有哪些:

    1.redux

    2.react-redux

    3.redux-thunk

    4.(可选,这是常用的页面路由,和redux无关)react-navigtion

    先说一下我接下来要讲的顺序:

    1.介绍redux以及基础用法。
    
    2.通过结合项目的方式从外向里直接介绍如何在react-native中使用redux、其中会带着讲解react-redux和redux-think。
    
    3.用法举例。
    
    4.注意事项以及开发技巧。

    一:什么是redux?为什么会出现redux?redux和react的关系?

    我在这里借鉴阮一峰老师的话简述一下:

    react只是DOM的一个抽象层,并不是Web应用的完整解决方案。有很关键的两个方面,他没有涉及到

    1.代码结构
    2.组件交互

    所以说react没办法开发大型项目的,因为大型项目业务逻辑复杂,这两个方面恰恰是最需要的。

    理所当然,FaceBook在14年提出了Flux架构的概念,redux在15年就应景而生。用来解决react存在的这两个问题。

    redux是干什么的?用两句话总结,也就是redux的设计理念:

    (1)Web 应用是一个状态机,视图与状态是一一对应的。
    (2)所有的状态,保存在一个对象里面。

    理解了这两句话你就懂了redux。

    用大白话说,react配合redux实现的功能就是把state封装到一个对象里面,让所有视图都能拿到state来改变自己的视图内容。

    在这里大家可以参考阮一峰老师讲解的Redux:

    http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html

    这是我的转载地址:

    https://blog.csdn.net/sinat_30949835/article/details/79923631

    因为本节教程主要讲解的是在项目中实战、使用redux的。所以就不在赘述redux使用教程。接下来直接讲解使用方法。

    二:在ReactNative中使用redux。

    首先要讲一下:

    1.有人说“如果你不知道是否需要redux,那就是不需要他”。

    2.Redux的创造者Dan Abramov又补充了一句“只有遇到React实在解决不了的问题,你才需要Redux”。

    因为redux的用法十分复杂,但他解决的也是react解决不了或者十分复杂的问题。

    所以如果你打算在项目中使用Redux、那么你的项目一定是存在下面两种场景的。

    1.多交互。
    2.多数据源。

    举个例子:

    我有一个用户总页面user_page。

    在user_page这个页面上又两个按钮,他们分别登录login_page和个人信息user_info_page页面

    而且在另一个tab页面上又存在一个用户头像的图标。

    那么你需要在登录成功的同时,修改user页面和tab页面用户头像。

    你需要在user_info页面上点击退出登录的同时再次修改user页面和tab页面用户头像。

    而且要在没登录是现实登录按钮,登录时现实个人信息。

    又或者另一个例子:

    在一个商城中,几乎是存在商品的地方,都有加入购物车的功能。而你的购物车页面又存在于tab的分支中。那么你每在不同的页面选中了商品加入购物车,都需要刷新这个购物车。

    这就是多交互和多数据源的简单例子。

    我的同事使用了react中的DeviceEventEmitter,类似于原生开发中使用的广播。这样虽然也能实现,但是不够优雅,管理广播也存在局限性。所以在这个时候redux就派上用场了。

    扯跑偏了,马上拉回来:

    2.1 在react-native中使用redux之react-redux

    在react-native中使用redux直接使用是不大方便的,毕竟react-native和react还是有些许变化的,所以react的作者专门针对于react-native分装了一个库react-redux。

    在react-native项目中,将会同时使用redux和react-redux并使用中间件redux-thunk让使用更灵活化。

    1.redux

    2.react-redux

    3.redux-thunk

    在使用之前,大家必须要了解redux的几个基础知识点。

    1.action

    2.reducer

    3.store

    简述action:

    简述reducer:

    简述store:

    2.2 在react-native中使用redux之“上代码”

    新建ReactNative项目,如果你还不会创建项目请移步我的另一篇基础博文:ReactNative创建项目:

    创建指定版本的项目

    react-native init ReduxDemo --version 0.51.0

    并依次引入redux,因为我用了navigation做导航路由所以引入了react-navigation

    npm install --save redux
    npm install --save react-redux
    npm install --save redux-thunk
    npm install --save react-navigation

    创建好项目并引入库后,在根目录下创建app文件夹用来存放编写的项目代码。


    在app目录下分别创建actions、reducers、store文件夹。选择创建page文件夹用来存放普通页面。

    并创建Root.js、ActionType.js文件。


    首先介绍ActionType.js就是所有action的type的合集。代码如下。

    这里全部都是自定义的,你想起什么名字就起什么名字,做type判断用的。

    ActionType.js

    /**
     * create by AbyssKitty on 2018/01/18
     * 所有的Action的type的集合
     */
    
    //export const LOGIN_DENGLU = 'login_denglu'; //初始化状态 
    export const ACTION_GETWEATHER_INIT = 'action_getweather_init'; //
    export const ACTION_GETWEATHER_SUCCESS = 'action_getweather_success'; //

    然后我们在actions文件夹下,新建一个GetWeatherAction.js文件。

    GetWeatherAction.js

    /**
     * create by AbyssKitty on 2017/12/06
     * 获取天气预报的action
     */
    import * as TYPES from '../ActionType';
    /**
     * 获取天气预报的action
     */
    export function actionGetWeather(list){
        return (dispatch) => {
            //开始获取,发送一个dispatch
            dispatch(init(list));
            /**
             * 在这里假装做了一个类似于调接口的操作
             */
            //获取成功,发送一个dispatch
            dispatch(success(list));
        }
    }
    
    /**
     * 这里会通过dispatch把action送给reducer,TYPE是判断拿到的是哪个action。
     */
    function init(list){
        return{
            type : TYPES.ACTION_GETWEATHER_INIT,
            message : '开始获取',
            bean : list,
        }
    }
    
    function success(list){
        return{
            type : TYPES.ACTION_GETWEATHER_SUCCESS,
            message : '获取成功',
            bean : list,
        }
    }

    然后我们在reducers文件夹下新建一个item文件夹和一个IndexReducers.js文件

    在item文件夹下创建一个reducer文件(注item下存放所有的reducer文件,并必须在IndexReducers.js中全部配置)

    创建GetWeatherReducer.js文件

    /**
     * create by AbyssKitty on 2017/12/06
     * reducers
     */
    import * as TYPES from '../../ActionType';
    
    /**
     * 这里可以初始化一个默认的实体类
     */
    const initialState = {
      status: 'init',
      isSuccess: false,
      bean:null,
      message : '',
    }
    /**
     * 在这里可以拿到action并return给IndexReducers.js进行分发。
     * 
     * 根据type判断了是从哪个action过来的数据,并进行选择性return。
     */
    export default function getWeather(state = initialState, action) {
        switch (action.type) {
            case TYPES.ACTION_GETWEATHER_INIT: // 初始状态
                return Object.assign({}, state, {
                    status: 'init',
                    isSuccess: false,
                    bean : action.bean,
                    message : action.message,
                });
                break;
            case TYPES.ACTION_GETWEATHER_SUCCESS: // 初始状态
                return Object.assign({}, state, {
                    status: 'success',
                    isSuccess: true,
                    bean : action.bean,
                    message : action.message,
                });
                break;
            default:
                return state;
      }
    }

    我们需要通过IndexReducers.js来绑定所有的reducer。这里只有一个GetWeatherReducer所以就先绑定一个。

    IndexReducers.js

    /**
     * create by AbyssKitty on 2017/09/22
     * 事件分发 总模块
     */
    
    import { combineReducers } from 'redux';
    import GetWeatherReducer from './item/GetWeatherReducer';
    
    //这里面必须要有初始数据 - 否则报错
    const rootReducer = combineReducers({
        //GetWeatherReducer : GetWeatherReducer,
        GetWeatherReducer,
    });
    
    export default rootReducer;

    然后在store文件夹中创建Store.js文件。通过thunk进行分发。

    Store.js

    /**
     * create by AbyssKitty on 2017/12/06
     * store 的配置文件
     */
    
    import {createStore, applyMiddleware} from 'redux';
    import thunkMiddleware from 'redux-thunk';
    import rootReducer from '../reducers/IndexReducers';
    
    /**
     * 
     * 
     * 
     */
    
    const createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore);
    
    export default function configureStore(initialState) {
      const store = createStoreWithMiddleware(rootReducer, initialState);
      return store;
    }

    最后编写Root.js文件。用react-redux的Provide包裹住整个项目,并使用store属性。

    Root.js

    /**
     * create by AbyssKitty on 2017/12/06
     * 程序入口 通过包裹初始化
     */
    import React, { Component } from 'react';
    import { Provider } from 'react-redux';
    import configureStore from './store/Store';
    import { AppNavigator } from './navigator/navigator';
    
    const store = configureStore();
    
    /**
     * react-redux介绍
     * 阮一峰博客:http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux.html
     * React-Redux 将所有组件分成两大类:UI 组件(presentational component)和容器组件(container component)。
     * UI:
     * 只负责 UI 的呈现,不带有任何业务逻辑
     * 没有状态(即不使用this.state这个变量)
     * 所有数据都由参数(this.props)提供
     * 不使用任何 Redux 的 API
     * 容器:
     * 负责管理数据和业务逻辑,不负责 UI 的呈现
     * 带有内部状态
     * 使用 Redux 的 API
     */
    /**
     * Provider详解。
     * 他是react-redux提供的,用来让子组件可以通过props直接拿到state了。
     * (注:如果不用react-redux,就需要一层一层的传值,十分繁琐。)
     * Provider用法。用他包裹住整个app组件,他的子组件就全部可以通过props拿到state了。
     */
    export default class Root extends Component {
      render() {
        return (
          <Provider store={store}>
            <AppNavigator />
          </Provider>
        );
      }
    }

    这里的AppNavigator是react-navigation的StackNavigator不做赘述。

    navigator.js

    import React from 'react'
    import { StackNavigator } from 'react-navigation'
    
    import Main from '../page/Main';
    import Redux1 from '../page/Redux1';
    
    export const AppNavigator = StackNavigator({
    
        Main : {screen : Main},
        Redux1 : {screen : Redux1},
    });

    main和redux1是我的两个页面。

    然后使用App.js包裹住Root.js

    react-native 0.50以上 只有index.js和App.js

    react-native 0.50以下 有index.android.js和index.ios.js

    App.js

    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     * @flow
     * 
     * create by AbyssKitty on 2018-04-11
     */
    
    import React, { Component } from 'react';
    import {
      Platform,
      StyleSheet,
      Text,
      View
    } from 'react-native';
    import Root from './app/Root';
    
    export default class App extends Component {
      render() {
        return (
          <Root/>
        );
      }
    }
    
    const styles = StyleSheet.create({
      
    });
    

    ok这样就已经继承好了,接下来就是使用详情的讲解了。

    2.3 在react-native中使用redux之如何使用

    上面的代码大家已经知道我已经创建好了两个页面

    用法呢很简单。我这里简述一下:

    1.引入import { connect } from 'react-redux';
    2.在末尾加入
    function select(store) {
        return {
            GetWeatherReducer : store.GetWeatherReducer,
        }
    }
    
    export default connect(select)(Main);
    
    就是把这个组件用connect包裹住就能拿到store。
    注意export default已经拿到下面来了,上面的class前面的导出要删掉,Main是就是class的名字。
    GetWeatherReducer就是reducer集合里的名字。

    然后再生命周期中拿到props

    /**
         * 生命周期 - props发生变动时的操作,建议将回调代码在这里处理
         * @param {*} nextProps 
         */
        componentWillReceiveProps(nextProps){
            if(nextProps.GetWeatherReducer != null){
                if(nextProps.GetWeatherReducer.status == 'success'){
                    this.setState({
                        image : 2,
                    })
                }else{
                    this.setState({
                        image : 1,
                    })
                }
                this.setState({
                    text : nextProps.GetWeatherReducer.status,
                })
            }
        }
    
        /**
         * 生命周期 - 因为state变动频繁,不建议将redux的回调代码在这里处理,而且这里面是不能进行setState的操作的。
         * @param {*} nextProps 
         * @param {*} nextState 
         */
        shouldComponentUpdate(nextProps,nextState){
            console.log("执行了shouldComponentUpdate");
        }

    发送的话:

    1.引入
    import { connect } from 'react-redux';
    import { actionGetWeather } from '../actions/GetWeatherAction';
    2.代码中使用:let s = '123456';
    this.props.dispatch(actionGetWeather(s));进行发送action。

    下面是两个类的详细用法。

    下面是两个类的详细用法。

    Main.js

    import React, { Component } from 'react';
    import {
        StyleSheet,
        Text,
        View,
        Image,
        TouchableHighlight,
    } from 'react-native';
    
    import { connect } from 'react-redux';
    
    class Main extends Component {
        static navigationOptions = ({ navigation, screenProps }) => ({
            header:null,
        })
    
        constructor(props) {
            super(props);
            //设置状态
            this.state = {
                image : 1,
                text : '',
            }
        }
    
        goReduxPage = () => {
            this.props.navigation.navigate("Redux1");
        }
    
        goPropsPage = () => {
    
        }
    
        componentDidMount(){
            this.setState({
                text : '',
            })
        }
    
        quit = () => {
            this.setState({
                text:'',
                image : 1,
            })
        }
    
        /**
         * 生命周期 - props发生变动时的操作,建议将回调代码在这里处理
         * @param {*} nextProps 
         */
        componentWillReceiveProps(nextProps){
            if(nextProps.GetWeatherReducer != null){
                if(nextProps.GetWeatherReducer.status == 'success'){
                    this.setState({
                        image : 2,
                    })
                }else{
                    this.setState({
                        image : 1,
                    })
                }
                this.setState({
                    text : nextProps.GetWeatherReducer.status,
                })
            }
        }
    
        /**
         * 生命周期 - 因为state变动频繁,不建议将redux的回调代码在这里处理,而且这里面是不能进行setState的操作的。
         * @param {*} nextProps 
         * @param {*} nextState 
         */
        shouldComponentUpdate(nextProps,nextState){
            console.log("执行了shouldComponentUpdate");
        }
    
        render() {
    
            return (
                <View style = {styles.bgView}>
                    <Text>
                        {
                            "本Demo主要功能:\n"+
                            "1.redux在本页面或者跨页面修改全局组件内容\n"+
                            "2.通过props,state父子组件交互"
                        }
                    </Text>
                    
                    <TouchableHighlight style = {styles.touchableView} underlayColor={"#f4f4f4"} onPress={() => this.goReduxPage()}>
                        <View style = {styles.buttonView}>
                            <Text style = {{ fontSize : 16,color : "#FFFFFF" }}>
                                { 'redux' }
                            </Text>
                        </View>
                    </TouchableHighlight>
    
                    <TouchableHighlight style = {styles.touchableView} underlayColor={"#f4f4f4"} onPress={() => this.goPropsPage()}>
                        <View style = {styles.buttonView}>
                            <Text style = {{ fontSize : 16,color : "#FFFFFF" }}>
                                { 'props' }
                            </Text>
                        </View>
                    </TouchableHighlight> 
    
                    {/* 动态区域 */}
                    <View style = {{ width : '100%',height : 100, backgroundColor : "EAEEEF" ,justifyContent : 'center', alignItems : 'center',}}>
                        {
                            this.state.image == 1 ? 
                            <Image source = {require("../images/heimao.png")}
                                style = {{ width : 40,height : 40,borderRadius:20 }}/>
                            :
                            <Image source = {require("../images/bgshuiguo.png")}
                                style = {{ width : 40,height : 40,borderRadius:20 }}/>
                        }
                        <Text style = {{color:"FF0000",fontSize : 14}}>
                            { this.state.text }
                        </Text>
                    </View>
    
                    <TouchableHighlight style = {styles.touchableView} underlayColor={"#f4f4f4"} onPress={() => this.quit()}>
                        <View style = {styles.buttonView}>
                            <Text style = {{ fontSize : 16,color : "#FFFFFF" }}>
                                { 'clear' }
                            </Text>
                        </View>
                    </TouchableHighlight> 
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        bgView : {
            flex : 1,
            justifyContent : 'center', 
            alignItems : 'center',
            backgroundColor : '#FFFFFF',
        },
        touchableView : {
            margin : 6,
        },
        buttonView : {
            width : 100,
            height : 40,
            backgroundColor : "#0000FF",
            borderRadius : 5,
            flexDirection : 'row', 
            justifyContent : 'center', 
            alignItems : 'center',
        },
    });
    
    function select(store) {
        return {
            GetWeatherReducer : store.GetWeatherReducer,
        }
    }
    
    export default connect(select)(Main);

    Redux1.js

    import React, { Component } from 'react';
    import {
        StyleSheet,
        Text,
        View,
        TouchableHighlight,
    } from 'react-native';
    
    import { connect } from 'react-redux';
    import { actionGetWeather } from '../actions/GetWeatherAction';
    
    class Redux1 extends Component {
        static navigationOptions = ({ navigation, screenProps }) => ({
            header:null,
        })
    
        constructor(props) {
            super(props);
            //设置状态
            this.state = {
                
            }
        }
    
        quit = () => {
            this.props.navigation.goBack();
        }
    
        stateRedux = () => {
            let s = '123456';
            this.props.dispatch(actionGetWeather(s));
        }
    
        render() {
            return (
                <View style = {styles.bgView}>
                     <TouchableHighlight style = {styles.touchableView} underlayColor={"#f4f4f4"} onPress={() => this.stateRedux()}>
                        <View style = {styles.buttonView}>
                            <Text style = {{ fontSize : 16,color : "#FFFFFF" }}>
                                { '发送' }
                            </Text>
                        </View>
                    </TouchableHighlight>
    
                    <Text style = {{color:"#000000",fontSize : 14}}>
                        {
                            this.props.GetWeatherReducer == null ? 
                            "" 
                            : 
                            this.props.GetWeatherReducer.status
                        }
                    </Text>
    
                    <TouchableHighlight style = {styles.touchableView} underlayColor={"#f4f4f4"} onPress={() => this.quit()}>
                        <View style = {styles.buttonView}>
                            <Text style = {{ fontSize : 16,color : "#FFFFFF" }}>
                                { 'quit' }
                            </Text>
                        </View>
                    </TouchableHighlight>
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        bgView : {
            flex : 1,
            justifyContent : 'center', 
            alignItems : 'center',
            backgroundColor : '#FFFFFF',
        },
        touchableView : {
            margin : 6,
        },
        buttonView : {
            width : 100,
            height : 40,
            backgroundColor : "#0000FF",
            borderRadius : 5,
            flexDirection : 'row', 
            justifyContent : 'center', 
            alignItems : 'center',
        },
    });
    
    function select(store) {
        return {
            GetWeatherReducer : store.GetWeatherReducer,
        }
    }
    
    export default connect(select)(Redux1);

    三:注意事项和技巧

    未完待续......


    展开全文
  • 用户场景: 用户操作某一功能时,提示去登陆页面,从登陆页面跳到快速登录或者注册页面,快速登录或者注册完,需要跳回到用户原来操作浏览的页面利用goback返回多个页面登陆页面_gotoScreen(screenName,params){ ...

    用户场景: 用户操作某一功能时,提示去登陆页面,从登陆页面跳到快速登录或者注册页面,快速登录或者注册完,需要跳回到用户原来操作浏览的页面
    利用goback返回多个页面

    登陆页面
    _gotoScreen(screenName,params){
    const {navigate}=this.props.navigation;
    navigate(screenName,params);
    }
    this._gotoScreen('ForgetPassword',{gobackKey:this.props.navigation.state.key})

    快速登录或者注册页面
    this.props.navigation.goBack(this.props.navigation.state.params.gobackKey);


    用户场景: 用户从我的评价列表拿到数据,传参数给下一页面,修改完编辑评论页面,发表修改后的评论 跳回到上一页面
    处理goback返回上一页面而无法刷新数据的
    const {navigate} = this.props.navigation;
    navigate('ReviseComment', {params: item, callBackData: this._refresh});
    //返回时执行上一页面的刷新数据方法
    //执行上一页面的刷新数据方法
    this.props.navigation.state.params.callBackData();
    this.props.navigation.goBack();

    注意事项:如果此页面是可从多个页面过来,就必须注意在需要的页面执行此操作,否则app会报错
    展开全文
  • 背景: 在做项目时使用React-Navigation进行页面管理。有两个需求 ... 2:从当前的通讯录的一个页面跳转到我的的一个子页面,但是当点击这个子页面的返回键...一:goBack返回到指定页面 分析: 在React-Navigation...

    背景:
    在做项目时使用React-Navigation进行页面管理。有两个需求
    在这里插入图片描述
    1:在我的中进入界面,从主界面A进入B,B进入C,C进入D,在D中点击返回键要求直接返回到A中。
    2:从当前的通讯录中的一个页面跳转到我的中的一个子页面,但是当点击这个子页面的返回键时,他会返回到我的中的上一个界面,而不是通讯录中的那个页面。

    一:goBack返回到指定页面

    分析:
    React-Navigation中,他是通过栈的形式进行页面管理的。简单的描述一下,首先通过createBottomTabNavigator创建一个BottomTabNavigator并指定每一个Tab的首页,就是上图所示的底部导航栏。之后通过createStackNavigator为每一个Tab创建stack,并将这个Tab中的所有的页面放进去。在进行页面切换时,他是以栈帧的进出的形式进行管理的。
    如图:是真tm的丑。
    在这里插入图片描述
    如图:从A进入B就相当于是在栈中增加栈帧B。类似的,进入到D中之后,他会将CD这两个栈帧都放到栈中进行管理。如果点击默认的返回键,就相当于是将栈帧推出栈。同样的推出也是一个一个推出。此时想要从D一步返回到A,该怎么搞????
    如果只是简单的调用goBack函数,并且在括号内填写routeName,那么是绝对不会生效的,相信看到这篇文章的人,这个坑都已经走过了。
    接下来看一下React-Navigation官方文档中对于goBack()的解释:
    在这里插入图片描述
    如果想返回到特定的页面,需要获取到相应的SCREEN_KEY。而不是routeName。这个SCREEN_KEY是怎么获取的?要获取哪一个页面的SCREEN_KEY呢?
    接下来就解决上面的两个问题:
    1:使用navigation.state.key就可以获取到当前页面的SCREEN_KEYstate表示屏幕当前的状态或者是路线。根据官网所描述,他将会返回一个对象,对象中包含三个属性,分别是key,params,routeName
    2:知道了如何去获取SCREEN_KEY,那接下来该获取哪个页面的SCREEN_KEY呢????
    在上面对官网的截图也已经说的很明白了navigation.goBack(SCREEN_KEY_B) // will go to screen A from screen B。从页面B返回到页面A需要获取到页面B的SCREEN_KEY。因此如果我想从D直接一步返回到页面A中需要在D中调用goBack函数时使用B的SCREEN_KEY作为参数。
    上代码:
    1:在B页面通过对子组件传值的方式将当前页面的key一步一步的传输到D页面中:

    <AllDynamicComments backKey={this.props.navigation.state.key}/>
    

    2:在D页面通过设置navigationOptions来将导航栏进行设置,同时定义一个函数设置goBack()函数,:

     // 定义navigationOPtions,设置标题栏的返回按钮
     static navigationOptions = (
        (props) => {
          return {
            headerBackTitle: null,
            headerLeft: (
              <TouchableOpacity onPress={props.navigation.state.params.backTest}>
                <Image style={Styles.profileMarginRight20} source={require('../../../../img/threePoints.png')} />
              </TouchableOpacity>
            )
          }
        }
      )
    // 定义函数
    backTest = () => {
        this.props.navigation.goBack(this.props.navigation.getParam('backKey', ''))
      }
      // 使用生命周期函数进行setParams,保证在navigationOptions中可以使用backTest函数
      componentDidMount () {
        this.props.navigation.setParams({ backTest: this.backTest })
      }
    

    额外解释一下:
    由于从前一个页面是通过navigation.navigate(action,params)这种方式将backKey传过来的,所以取值时也应该使用this.props.navigation.getParam('backKey', '') 这种方式取值。
    此时点击D页面的返回键就可以直接从D跳回A。

    二:不同栈之间的页面跳转之后的返回

    在这里插入图片描述
    在左边的stack中通过(1)进入右边的stack中的最上面的栈帧,当点击返回键时希望他能够通过(2)跳转到返回原页面,但是他是通过(3)返回到上一个页面的。
    发现自己真的SB -_-。尝试了好多的方法,有push,还有goBack()。但是后来想了一下React-Navigation的设计思想,他是通过栈的形式进行页面的管理。他们是在不同的stack中的,因此不在一个圈子,怎么能相互串门?只能是肉包子打狗,有去无回,没有往来的。
    上代码:

    const LeftStack = createStackNavigator({
      LeftScreen1: { screen:  LeftScreen1, navigationOptions: { headerTitle: ' LeftScreen1' } },
      LeftScreen2: { screen: LeftScreen2, navigationOptions: { headerTitle: ' LeftScreen2' } }
    })
    const RightStack = createStackNavigator({
      RightScreen1: { screen: RightScreen1, navigationOptions: { headerTitle: 'RightScreen1' } },
      RightScreen2: { screen: RightScreen2, navigationOptions: { headerTitle: 'RightScreen2' } }
    })
    

    LeftScreen2进入到RightScreen2但是返回的时候是返回不到LeftScreen2中的。因此直接在上边加上RightScreen2的栈帧就OK了!!! 我靠。我TM…

    const LeftStack = createStackNavigator({
      LeftScreen1: { screen:  LeftScreen1, navigationOptions: { headerTitle: ' LeftScreen1' } },
      LeftScreen2: { screen: LeftScreen2, navigationOptions: { headerTitle: ' LeftScreen2' } },
      RightScreen2: { screen: RightScreen2, navigationOptions: { headerTitle: 'RightScreen2' } }
    })
    const RightStack = createStackNavigator({
      RightScreen1: { screen: RightScreen1, navigationOptions: { headerTitle: 'RightScreen1' } },
      RightScreen2: { screen: RightScreen2, navigationOptions: { headerTitle: 'RightScreen2' } }
    })
    

    这样,RightScreen2就可以和LeftScreen1LeftScreen2融为一体了。成为了一个圈子的个体了。相互之间是有来往了。这样就搞定了。

    总结

    1:在使用时,多了解一下涉及思想,有时就可以将复杂问题简单化。
    2:使用goBack返回页面和navigate跳转到指定页面,对页面的影响是不同的,猜测可能会引起重新渲染。等问题,惭愧的是我并没有深究这个问题。
    3:有帮助的stackoverflow文章链接:
    https://stackoverflow.com/questions/45489343/react-navigation-back-and-goback-not-working
    4:有帮助的csdn文章链接:
    https://blog.csdn.net/noahchen666_qq_com/article/details/80452058
    5:非常感谢帮助,如有错误感谢指正

    展开全文
  • ViewA跳转到ViewB import React from "react";...import { Button, Text, View } from "react-native"; class ViewA extends React.Component { state = { selected: false }; onSelect = data => { this.se...

    ViewA跳转到ViewB

    import React from "react";
    import { Button, Text, View } from "react-native";
    
    class ViewA extends React.Component {
      state = { selected: false };
    
      onSelect = data => {
        this.setState(data);
      };
    
      onPress = () => {
        this.props.navigate("ViewB", { onSelect: this.onSelect });
      };
    
      render() {
        return (
          <View>
            <Text>{this.state.selected ? "Selected" : "Not Selected"}</Text>
            <Button title="Next" onPress={this.onPress} />
          </View>
        );
      }
    }
    

    ViewB

    import React from "react";
    import { Button } from "react-native";
    
    class ViewB extends React.Component {
      goBack() {
        const { navigation } = this.props;
        navigation.goBack();
        navigation.state.params.onSelect({ selected: true });
      }
    
      render() {
        return <Button title="back" onPress={this.goBack} />;
      }
    }
    

    语法类似于React中子组件向父组件传值。

    展开全文
  • 标签与url实现不同页面之间的跳转,利用浏览器的返回按钮返回之前浏览的页面,但是在React Native中却没有集成内嵌的全局栈来实现这个界面的跳转,因此需要使用第三方库来实现这个功能。React Navigation就是这样一...
  • react-navigationreact-navigation 是今年1月份新出的一款react-native导航组件, 才几个月github就三千多star, 半官方身份, fb推荐使用, 据称性能和效果跟原生差不多. 可能是react-native导航组件的未来主流. 但...
  • 先上代码,配合代码讲解一下使用方法, 我这有用到一个屏幕适配工具类,自己写的,使用方法和代码 请点这里 ...import React from 'react'; import { Text, StyleSheet, View, TouchableOpacity, Image...
  • 创建React Native App是Facebook与Expo联合开发的用于快速创建React Native应用的工具,创建React Native App可以在没有安装React Native的IDE(Nuclide,WebStorm等)时,可以将应用运行在Expo的客户端应用内,还...
  • import { StackActions } from "react-navigation"; const popAction = StackActions.pop({n: 1}); this.props.navigation.dispatch(popAction);
  • Nativgation 的返回 goBack可带参数的修改如下,StackRouter.js文件内的NavigationActions.Back内容修改如下: const key = action.key; let backRouteIndex = null ; if (key) { let backRoute ; if(key....
  • 本人学习React Native没有看过任何教学视频,都是按照官网一步步学习的。只研究了Android开发,所以下面的教程都是Android开发教程。 注意:未经允许不可私自转载,违者必究 React Native官方文档:...
  • react-native项目目录下,安装react-navigation包 npm install --save react-navigation 然后再安装react-native-gesture-handler包 npm install --save react-native-gesture-handler link所有原生依赖 react-...
  • 写在开头的话最近使用React-Native开发新应用,一开始使用的导航器是navigator,后来发现navigator有很多...总览React Native ,官方已经推荐使用 react-navigation 来实现各个界面的跳转和不同板块的切换。react-na
  • 欢迎大家关注【跨平台开发那些事】公众号,定期推...基于最新版本React Native实现JsBundle预加载,界面秒开优化 一、开源库介绍 今年1月份,新开源的react-natvigation库备受瞩目。在短短不到3个月的时间,gith...
  • the key property for goBack() is a dynamically created string, created by react-navigationwhenever navigate to a new route.goBack()参数key为react-navigation动态分配的,而不是指定的routeName,所以当在...
  • react-native-camera是一个非常好用的RN调用摄像头的第三方库,github地址: https://github.com/react-native-community/react-native-camera 使用的时候有几处坑,在这里记录一下开发过程,首先效果图: 使用时先...
  • 最近在做一个跨平台的项目 , 遇到两个问题 , 第一是Android的back键的默认行为是退出应用 , 而在我们的实际应用场景期望的并非如此 ; 第二就是使用 webview 时 , 我们期望 back 键执行的是 web 页面的 ...
1 2 3 4 5 ... 20
收藏数 1,404
精华内容 561
关键字:

native中goback react