从零搭建React-Native APP(长文)

原创 amandakelake 教程 框架与工具 540阅读 2018-03-09 19:43:49 举报

我在学习过程中喜欢做记录,分享的是我在前端之路上的一些积累和思考,也希望能跟大家一起交流与进步。
这是我的github博客,欢迎一起学习,欢迎star

一、须知

全文技术栈
核心库:React-Native@0.54.0
路由导航:React-Native-Navigation
状态管理:Redux、Redux-Thunk、Redux-Saga、Redux-persist
静态测试:Flow

本文适合有对React家族有一定使用经验,但对从零配置一个App不是很熟悉,又想要从零体验一把搭建app的感觉

我自己就是这种情况,中途参与到项目中,一直没有掌控全局的感觉,所以这次趁着项目重构的机会,自己也跟着从零配置了一遍,并记录了下来,希望能跟同学们一起学习,如果有说错的地方,也希望大家指出来,或者有更好的改进方式,欢迎交流。

如果有时间的同学,跟着亲手做一遍是最好的,对于如何搭建一个真实项目比较有帮助。整个项目已经上传到github,懒的动手的同学可以直接clone下来跟着看,欢迎一起完善,目前的初步想法是对一部分的同学有所帮助,后面有时间的话,可能会完善成一个比较健壮的RN基础框架,可以直接clone就开发项目那种本项目github仓库地址

这里对每个库或者内容只做配置介绍,不做基础用法讲解;

环境:mac,xcode
window的同学也可以看,不过需要自己搞好模拟器开发环境

二、快速建立一个RN APP

Getting Started · React Native
如果RN的基础配置环境没有配置好,请点击上方链接到官网进行配置

因为一开始就计划好了用React-Native-Navigation作为导航库,所以名字起得长了点,大家起个自己喜欢的吧

成功后会看到这个界面

三、React-Native-Navigation

1、安装与iOS配置

React Native Navigation - truly native navigation for iOS and Android
英文好的同学看着官方文档配就可以了,实在看不懂的可以对照着我下面的图看。
iOS的需要用到xcode,没做过的可能会觉得有点复杂,所以我跑了一遍流程并截图出来了
至于android的配置,文档写的很清晰,就不跑了。

1、安装最新版本
yarn add react-native-navigation@latest

2、添加xcode工程文件

图中的路径文件是指./node_modules/react-native-navigation/ios/ReactNativeNavigation.xcodeproj

3、把上面添加的工程文件添加到库中

4、添加路径

$(SRCROOT)/../node_modules/react-native-navigation/ios
记得图中第5点设置为recursive

5、修改ios/[app name]/AppDelegate.m文件

把整个文件内容替换成下面代码

2、基础使用

1、先新建几个页面,结构如图


每个index.js文件里面都是一样的结构,非常简单

2、src/index.js 注册所有的页面,统一管理

在这里先插一句,如果要引入Redux的话,就在这里直接传入storeProvider

3、App.js 修改app的启动方式,并稍微修改一下页面样式

目前能看到的app界面

3、页面跳转和传递参数

新建一个NextPage页面,记得到src/screen/index.js里面注册该页面

然后在src/screen/home/index.js文件里面加一个跳转按钮,并传递一个props数据

四、状态管理:Redux

没有相关概念的小伙伴请先看看官方文档,下面直接讲目录结构配置
自述 · GitBook

1、安装

yarn add redux react-redux

2、目录构建

一般来说,有以下两种目录构建方式
一是把同一个页面的action和reducer写在同一个文件夹下面(可以称之为组件化),长下面这样

二是把所有的action放在一个文件夹,所有的reducer放在一个文件夹,统一管理

这两种方式各有好坏,不在此探究,这里我用第二种

一通操作猛如虎

以上命令敲完后,目录结构应该长下面这样,每个页面都分别拥有自己的action和reducer文件,但都由index.js文件集中管理输出

3、创建store、action、reducer

关于创这三块内容的先后顺序,理论上来说,应该是先有store,然后有reducer,再到action
但写的多了之后,就比较随心了,那个顺手就先写哪个。
按照我自己的习惯,我喜欢从无写到有,比如说
store里面要引入合并后的reducer,那我就会先去把reducer给写了
import combinedReducer from '../reducer';
但写reducer之前,好像又需要先引入action,所以我由可能跑去先写action

这里不讨论正确的书写顺序,我就暂且按照自己的习惯来写吧

action
我喜欢集中管理的模式,所以所有的antion我都会集中起来
index.js文件作为总的输出口
这里定义了所有的action-type常量

然后去写其他各自页面的action.js文件,这里只以home页面作为例子,其他页面就不写了,打开action/home.js文件

reducer
先写一个home页面的reducer,打开reducer/home.js文件
其他页面也同理

然后把所有子reducer页面合并到index.js文件进行集中输出

还可以引入combineReducers方法,和自己写也是一样的

创建store

创建好reducer之后,打开store/index.js文件

就这么简单,store就创建好了

4、store注入

使用过redux的同学都知道,react-redux上场了,它提供了Providerconnect方法

前面有提到react-native-navigation注入redux的方式,其实差不多
但需要每个子页面都注入store、Provider
src/index.js修改如下

App.js修改执行页面注册的方法即可

5、初步体验redux

现在来体验一下redux,打开src/screen/home/index.js文件

import两个方法

导入action

定义两个方法,并connect起来

现在在页面上打印initCount来看一下,核心代码

src/screen/home/index.js完整代码如下

从页面可以看到,已经读到状态树里面的数据了

让我们再来试一下action的加法和减法
src/screen/home/index.js完整代码如下

现在再来验证下一个东西,这个页面改完store里面的状态后,另一个页面会不会同步
src/mine/index.js文件修改如下


在该页面上读取同一个数据this.props.home.initCount,然后在第一个页面上加减数据,再看该页面,会发现initCount也同步变化
也就是说明:我们已经在进行状态管理了

五、状态跟踪redux-logger

这个时候,我们会发现,虽然状态共享了,但目前还没有办法跟踪状态,以及每一步操作带来的状态变化。

但总不能每次都手动打印状态到控制台里面吧?

这时候,上面装的redux-logger就上场了
它大概长下面这样,把每次派发action的前后状态都自动输出到控制台上

具体使用看下官方文档,很简单,直接上代码吧
GitHub - evgenyrodionov/redux-logger: Logger for Redux

安装(之前已经安装过了,没装的可以再装一下)
yarn add redux-logger

使用
它作为一个中间件,中间件的用法请回redux官网查阅
store/index.js文件修改如下

command+R刷新一下模拟器,再点击一下+2,看看控制台是不是长下面这样?

接下来每次派发action,控制台都会自动打印出来,是不是省心省事?

六、异步管理:redux-thunk

redux-thunk是什么请移步Redux异步控制
出发点:需要组件对同步或异步的 action 无感,调用异步 action 时不需要显式地传入 dispatch

通过使用指定的 middleware,action 创建函数除了返回 action 对象外还可以返回函数。这时,这个 action 创建函数就成为了 thunk

当 action 创建函数返回函数时,这个函数会被 Redux Thunk middleware 执行。这个函数并不需要保持纯净;它还可以带有副作用,包括执行异步 API 请求。这个函数还可以 dispatch action,就像 dispatch 前面定义的同步 action 一样
thunk 的一个优点是它的结果可以再次被 dispatch

1、安装

yarn add redux-thunk

2、注入store

作为一个中间件,它的使用方式和上面logger一样,直接引入即可

3、使用方式

action/home.js文件修改如下

action/index.js总入口记得加上对应的action
export const HOME_GET_SOMEDATA = 'HOME_GET_SOMEDATA';

题外话:封装请求函数post

此处稍微插入一句,关于封装请求函数post(以下是精简版,只保留了核心思想)

公用的方法和函数都封装在utils文件夹中
utils/fetch.js文件如下

八、异步管理:Redux-Saga

基本概念请移步自述 | Redux-saga 中文文档

出发点:需要声明式地来表述复杂异步数据流(如长流程表单,请求失败后重试等),命令式的 thunk 对于复杂异步数据流的表现力有限

1、安装

yarn add redux-saga

2、创建saga文件

创建顺序有点像reducer
我们先创建saga相关文件夹和文件,最后再来注入store里面

先修改saga/home.js文件

saga/mine.js文件
export const mineSagas = []
saga/popularize.js文件
export const popularizeSagas = []

saga/index.js文件作为总输出口,修改如下

3、把saga注入store

store/index.js文件修改

九、数据持久化:redux-persist

GitHub - rt2zz/redux-persist: persist and rehydrate a redux store
顾名思义,数据持久化,一般用来保存登录信息等需要保存在本地的数据;
因为store中的数据,在每次重新打开app后,都会回复到reducer中的initState的初始状态,所以像登录信息这种数据就需要持久化的存储了。
RN自带的AsyncStorage可以实现这个功能,但使用起来比较繁琐,而且没有注入到store中去,没办法实现统一状态管理,所以redux-persist就出场了

安装
yarn add redux-persist

注入store
store/index.js文件完整代码如下

到目前为止,我们已经引入了redux-logger、redux-thunk、redux-saga、redux-persist,核心开发代码库已经配置完毕了

React Native填坑之旅--Flow篇(番外)

九、静态测试:Flow

待更新,这有一篇链接可以先看
React Native填坑之旅—Flow篇(番外) - full stack dev stills - SegmentFault 思否

后话

到目前为止,我们已经引入了redux-logger、redux-thunk、redux-saga、redux-persist

核心开发代码库已经配置完毕了

项目已经传上github,欢迎star

本项目github仓库地址

接下来还有一些可以作为开发时的辅助性配置,比如Flow 、Babel(RN初始化时已经配好了)、Eslint等等

另外,既然是App,那最终目的当然就是要上架App Store和各大安卓市场,后面可能还会分享一下关于极光推送jPush、热更新CodePush、打包上传审核等方面的内容。

我在学习过程中喜欢做记录,分享的是我在前端之路上的一些积累和思考,也希望能跟大家一起交流与进步。
这是我的github博客,欢迎一起学习,欢迎star

评论 ( 4 )
最新评论
amandakelake 3F 2018-03-15 15:58:51 4F

过段时间整理下就写,最近在捣鼓react和redux源码

18323947911 2018-03-15 09:35:45 3F

已点star,后面一定要讲解极光推送,还有一些调用原生的内容啊

folat 2018-03-09 20:59:20 2F

good!

大神M 2018-03-09 20:49:53 1F

学到了!