本文转自:文章地址:http://blog.csdn.net/u013718120/article/details/72357698

继react-navigation发布已经过去半年的时间,想必React Native的玩家早已玩转于手掌了。如果你还不了解,就out啦~还在等什么?

React Native未来导航者:react-navigation 使用详解

Redux框架给开发者带来的优势是显而易见的。它好比Android中的MVP架构一样,使得复杂的业务逻辑和视图状态变得简单、清晰。如何将react-navigation和Redux结合到一起呢?本篇博客就来唠唠。

在搞定Redux与react-navigation整合之前,我们有必要先了解下在没有使用react-navigation导航下的Redux项目架构,先来看一个简单的Redux项目目录:

一般情况下,Redux项目中都会包含如下几个目录:

(1)Action

(2)Reducer

(3)Store

熟悉Redux的玩家肯定对这三个模块肯定都不陌生。Action中负责分发用户行为;Reducer接收Action,并根据行为类型进行相应的逻辑处理,并返回最新状态;Store中负责Action和Reducer的交互,并记录Reducer处理的最新状态。并且还可以应用中间件等;此时可利用react-redux将状态与视图绑定。这样,Action -> Controller -> View就完美的形成了闭环流程。下面我们分别看下三者之间是如何衔接的。

1、Action

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export let main = (url, params, isLoading, isLoadMore, isRefreshing) => {
    return dispatch => {
 
        // 1.发出拉取数据的信号
        dispatch(loadMainContent(isLoading, isLoadMore, isRefreshing));
 
        // 2.请求网络
        return HttpUtil.fetchGet(url, params,
            (responseObj) => {
                dispatch(receiveMainContent(responseObj.result.bookList));
                console.info("success");
            },
            (error) => {
                dispatch(receiveMainContent([]));
                console.info("error" + error);
            }
        )
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let loadMainContent = (isLoading, isLoadMore, isRefreshing) => {
    return {
        type: types.LOAD_MAIN_LIST,
        isLoading: isLoading,
        isLoadMore: isLoadMore,
        isRefreshing: isRefreshing
    }
}
 
let receiveMainContent = (mainList) => {
    return {
        type: types.GET_MAIN_LIST,
        mainList: mainList
    }
}

如上代码所示,在main Action中,我们定义了不同的Action行为,并通过dispatch进行分发。

2、Reducer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const initState = {
    mainList: [],
    isLoading: true,
    isLoadMore: false,
    isRefreshing: false
}
 
let mainReducer = (state = initState, action) => {
    switch (action.type) {
        case types.LOAD_MAIN_LIST:
            return Object.assign({}, state, {
                isLoading: action.isLoading,
                isLoadMore: action.isLoadMore,
                isRefreshing: action.isRefreshing
            });
        case types.GET_MAIN_LIST:
            return Object.assign({}, state, {
                isLoading: false,
                isRefreshing: false,
                mainList: state.isLoadMore ? state.mainList.concat(action.mainList) : action.mainList
            })
        default:
            return state;
    }
}

上面代码定义了对应的Reducer,用来接收Action的行为,并进行处理,最终返回最新状态State。

3、整合Reducer

1
2
3
4
export default rootReducer = combineReducers({
    Main,
 
})

4、Store

1
2
3
4
let store = createStore(rootReducer, {}, compose(
  applyMiddleware(thunk),
  window.devToolsExtension ? window.devToolsExtension() : f => f
))

Store相对简单,因为Redux本身没有异步概念,不能直接使用setTimeOut等,但是网络处理需要异步进行,并且结果是异步返回,所以为了处理此种情况,可以使用中间件react-thunk帮助我们完成。

5、Connect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import App from './components/app';
import store from './store/store';
 
export default class Root extends Component {
 
    render() {
        return (
            <Provider store={store}>
                <App />
            </Provider>
        )
    }
}

使用react-redux将store传递到Provider,从而将Redux和视图层绑定在一起,完成Action -> Reducer ->  Store -> View的整体连接。

上面代码中App即视图的入口,react-navigation其实就充当了程序的入口,负责视图界面之间的跳转交互。

1
2
3
4
5
const AppNavigator = StackNavigator(
    {
        Splash: { screen: SplashScene },
    }

在react-navigation中使用navigate来实现界面间跳转行为。此时我们可以理解为Redux中的dispatch,即一个用户行为。

1、dispatch的触发需要Reducer的接收,所以我们需要定义react-navigation的Reducer:

1
2
3
4
5
6
7
8
import Routers from './Router';
 
const navReducer = (state,action) => {
    const newState = Routers.router.getStateForAction(action, state);
    return newState || state;
}
 
export default navReducer;

Router中就是我们定义的react-navigation的StackNavigator。navReducer即为接收跳转状态的Reducer,代码中我们通过获取StackNavigator的Action来返回最新的处理状态。

2、在rootReducer中注册该reducer:

1
2
3
export default rootReducer = combineReducers({
    Nav
})

3、Store中仍然是注册rootRecuder,使用中间件等等。

4、App首页中绑定(app.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@connect(state => ({
    nav: state.nav
}))
 
class AppWithNavigationState extends Component {
    render() {
        return (
            <Router
                navigation={addNavigationHelpers({
                    dispatch: this.props.dispatch,
                    state: this.props.nav
                })}
            />
        );
    }
}
 
export default class App extends Component {
 
    render() {
        return(
            <Provider store={ store }>
                <AppWithNavigationState/>
            </Provider>
 
        )
    }
}

以上代码定义在程序入口中,从代码可以看到,首先使用@connect绑定nav的state,即NavReducer中返回的state。Router就是我们的StackNavigator,对其添加addNavigationHelpers,并将dispatch和state传入。dispatch和nav就是Redux中分发的行为和状态,这样去触发react-navigation的改变。最后使用Provider包含并将store注入到Provider。

总结下流程:

(1)定义navReducer,返回导航状态。(跳转State)

(2)注册reducer。 (将navReducer添加到rootReducer)

(3)创建store。(store中注入rootReducer)

(4)程序入口中将store注入Provider。(Provider将store注入StackNavigator)

(5)@connect获取最新导航状态。(将StackNavigator于=与Redux绑定)

(6)设置StackNavigator的addNavigationHelpers,并将状态和行为传入。(StackNavigator接收到Reducer返回的最新状态,执行相应改变(跳转等))

以上步骤执行完,此时,程序会在@connect抛出错误,因为我们使用了@描述符,所以需要引入如下第三方库:

1
"babel-plugin-transform-decorators-legacy": "^1.3.4"

(1)npm i babel-plugin-transform-decorators-legacy --save -dev

(2)项目根目录找到  文件,打开添加如下:

1
2
3
4
{
  "presets": ["react-native"],
  "plugins":["transform-decorators-legacy"] // 添加引用插件
}

ok,到此通过以上步骤,我们就将Redux和react-navigation整合在一起啦~

老规矩,源码奉上,点击下载

刚创建的React Native交流11群:112490774,欢迎各位大牛,React Native技术爱好者加入交流!同时博客右侧欢迎微信扫描关注订阅号,移动技术干货,精彩文章技术推送!

尊重原创,转载请注明:From Sky丶清(http://www.lcode.org) 侵权必究!

引用原文:http://www.lcode.org/react-navigation-redux/

写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,文章可以转载,无需版权。希望尽自己的努力,做到更好,大家一起努力进步!

如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!

React-Navigation与Redux整合详解的更多相关文章

  1. idea spring+springmvc+mybatis环境配置整合详解

    idea spring+springmvc+mybatis环境配置整合详解 1.配置整合前所需准备的环境: 1.1:jdk1.8 1.2:idea2017.1.5 1.3:Maven 3.5.2 2. ...

  2. react第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制)

    第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制) 课程目标 深入理解和掌握事件的冒泡及捕获机制 理解react中的合成事件的本质 在react组件中合理的使用原生事件 ...

  3. React源码 commit阶段详解

    转: React源码 commit阶段详解 点击进入React源码调试仓库. 当render阶段完成后,意味着在内存中构建的workInProgress树所有更新工作已经完成,这包括树中fiber节点 ...

  4. 【redux】详解react/redux的服务端渲染:页面性能与SEO

        亟待解决的疑问 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染)   react客户端渲染的一大痛点就是首屏渲染速度慢问题,因为react是一个单页面应用,大多数的资源需要在首次渲染前就加载 ...

  5. 翻译 | 玩转 React 表单 —— 受控组件详解

    原文地址:React.js Forms: Controlled Components 原文作者:Loren Stewart 译者:小 B0Y 校对者:珂珂君 本文涵盖以下受控组件: 文本输入框 数字输 ...

  6. 1、Shiro 安全框架与Spring 整合详解

    Apache Shiro 是一个安全认证框架,和 Spring Security 相比,在于他使用了比较简洁易懂的认证和授权方式.其提供的 native-session(即把用户认证后的授权信息保存在 ...

  7. Redux 笔记详解

    npm install --save redux 多数情况下,你还需要使用 React 绑定库和开发者工具. npm install --save react-redux npm install -- ...

  8. React生命周期及事件详解

    引用原文:http://blog.csdn.net/limm33/article/details/50942808 一.组件的详细说明和生命周期ComponentSpecs and Lifecycle ...

  9. Spring、SpringMVC、SpringData + JPA 整合详解

    原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7759874.html ------------------------------------ ...

随机推荐

  1. SurvivalShooter学习笔记(八.敌人管理器)

    敌人管理器:管理敌人的随机出生点创建 在场景中建立几个空物体,作为敌人的出生点 public class EnemyManager : MonoBehaviour { public PlayerHea ...

  2. layoutSubviews何时调用的问题

    本文转载至 http://www.cnblogs.com/pengyingh/articles/2417211.html 今天跟旺才兄学习了一下UIView的setNeedsDisplay和setNe ...

  3. eclipse新建maven web工程

    每次建maven项目,总会有问题.决定在这整理一次,避免以后浪费时间. 最后目录为 1.首先修改pom.xml 之前老是出现明明改了 java compiler 已maven update 一下就又变 ...

  4. Castle.MVC框架介绍

    Castle.MVC目前还在Castle的Sandbox中,只是在源代码管理中有,还没有向外发布版本,这里介绍多时Web的MVC,和Castle的MonoRail相比较,这个MVC可以Asp.Net的 ...

  5. [.NET网格计算框架] Alchemi

      Alchemi [.NET网格计算框架] 是 一个以使用简易为目的的Windows下的网格计算框架.它提供了:a)开发网格软件的编程环境 和 b)建造网格和运行网格软件的运行机制.       A ...

  6. libevent(了解)

    1 前言 Libevent是一个轻量级的开源高性能网络库,使用者众多,研究者更甚,相关文章也不少.写这一系列文章的用意在于,一则分享心得:二则对libevent代码和设计思想做系统的.更深层次的分析, ...

  7. sql 存储过程,最简单的添加和修改

    数据库表结构  <1>新增数据,并且按照"name" 字段查询,如果重复返回“error”=-100 ,如果成功返回ID,如果失败ID=0 USE [数据库]GOSET ...

  8. 【MarkDown】使用Html样式和折叠语法

    MarkDown很方便,但基本语法有些不足:比如无法使用折叠语法,无法让文字有不同的颜色. 这些功能可以实现,不过需要使用Html语法进行扩展.这篇文章主要是整理一下这些技巧,方便更好的使用. 一.折 ...

  9. 网络编程3 网络编程之缓冲区&subprocess&粘包&粘包解决方案

    1.sub简单使用 2.粘包现象(1) 3.粘包现象(2) 4.粘包现象解决方案 5.struct学习 6.粘包现象升级版解决方案 7.打印进度条

  10. Linux网络配置:设置IP地址、网关DNS、主机名

    查看网络信息 1.ifconfig eth0 2.ifconfig -a 3.ip add 设置主机名需改配置文件: /etc/hosts /etc/sysconfig/network vim /et ...