• layout: post
  • title: React Native 项目实战
  • date: 2016-10-18 15:02:29 +0800
  • comments: true
  • categories: ReactNative

文/tamic

地址:http://blog.csdn.net/sk719887916/article/details/53502401

本文以 Twitter 工程师 Bonnie Eisenman 撰写的 Learning React Native 一书的第九章内容为蓝本,总结了 React Native 在iOS项目上实践的一些经验。

项目组织结构

所有的新增文件均放在项目根目录下的 src 里,主要有包含各页面的 components 子目录、数据模型的 data 子目录、负责数据存取的 stores 子目录、公共样式定义 styles 子目录、存放资源图片等的 resources 子目录等。

index.ios.js 是 Native 应用的入口,该文件尽量简洁,指向 RN 项目里负责页面跳转的主文件 components/Zebreto.js。

案例项目简介

作者提供的示例项目包含三个页面,包含多副牌(Deck)的列表页、为选中的某副牌增加一张卡牌(Card)的页面、为某张卡牌选择答案(Review)的页面。

在列表页点击 Create Deck 按钮,按钮上方出现输入框,填写内容作为 Deck 的名称。点击 Deck 右侧按钮则进入增加卡牌页面,点击 Deck 左侧则进入 Review 的页面。

构建基础组件

公共样式

全局的颜色、字号等,可以在 js 里直接定义字典数据结构,然后 exports 以供外界访问。比如:

 js
 var palette = {
 pink: '#FDA6CD'
 };

module.exports = palette;

所以,像平安好房的应用可以参照上述结构定义 pa_orange 等色值。值得注意的是,我们也可以在一个 js 文件里定义多个字典,然后 exports 时将他们包含在花括号中即可。

module.exports = {fonts, color};

在使用上述结构时,就需要这么 import 了:

import { fonts, color } from '<PATH-OF-FILE>';

公共组件

我们不直接用 Text 组件,而是包装成 HeadingText 和 NormalText 供项目里的不同页面使用。同样的,为了代码重用与使用便捷,我们封装 Button、Input、LabeldInput 等组件。

其中 Button 组件构建在 TouchableOpacity 基础之上,支持 func 类型的属性以在点击时调用使用方的方法,也支持 View.propTypes.style 类型的属性以方便定制其样式等。

需要注意的是,为了让 Button 组件能包含其他子组件,我们使用了一个 object 类型的属性,然后在 render 时输出 children 即可。

HeadingText 和 NormalText 建立在 Text 组件之上,自定义样式是通过 Text.propTypes.style 类型的属性支持的。注意此处类型不同于前面 Button 使用过的样式类型。

Input 组件建立在 TextInput 之上,LabeledInput 组合了 Input 和 NormalText 两个组件,体现了复用的理念。

页面开发

Deck 列表页

数据建模

在 React Native 项目试点过程中,尚不熟悉 JavaScript 的类相关语法。当时都是用的字典:[

 js
 class Deck {
  constructor() {
 }
 }

 module.exports = Deck;

数据在本地使用 AsyncStorage存取,所有的存取方法均封装在 DeckStore.js里。

Reflux 架构

作者使用 Reflux 架构实现数据的单项流动,主要的两个概念便是 Store 和 Action 了。

用户在 View 上操作,触发 Action,示例 View 的事件响应代码如下:

DeckActions.createDeck(deck)

而 createDeck 是在 actions.js 里定义的:

export var DeckActions = Reflux.createActions([
  'createDeck'
]);

Store 的 init 方法里监听 Action:

js
var decksStore = Reflux.createStore({
 init() {
  this._decks = [];
  // ...
  this.listenTo(DeckActions.createDeck, this.createDeck);
 // ...
},

// ...

createDeck(deck) {
  this._decks.push(deck);

  this.emit();
}

// ...

 emit() {
  // ...
   this.trigger(this._decks);
 },
 });

module.exports = decksStore;

这样在 createDeck 这一 action 触发后,Store 变回执行 createDeck 方法以更新 Store 中的数据,再通过 emit 方法通知出去。

View 里面监听 DeckStore 的消息,将通知携带来的数据模型存在 state 里以触发 render 方法的执行(更新 UI)。

页面组装

src/components/Decks/index.js 是该页面的主文件,会包含一些子组件以完成整个页面的渲染。

在 index.js 的 render 方法里,将这一段代码封装在一个独立的工具方法,然后在 render 里面引用其返回的 UI 结构。

`js

_getDecks() {

if (!this.state.decks) {

return null;

}

return this.state.decks.map((deck) => {
  return (
    <Deck deck={deck} .../>
  );
});
},

使用高阶函数 map 根据每个 deck 数据对象生成对应的 Deck 标签,作为数据返回。

  render() {
    return (
      <View>
        {this._getDecks()}
        <DeckCreation .../>
      </View>
    );
  }

输入 Deck 名时比正常情况下多一行输入框,所以在 DeckCreation.js 中根据一个 state 变量分别返回不同的两个子组件:EnterDeck 和 CreateDeckButton。前者由公共组件 Input 和 CreateDeckButton 组合而成。CreateDeckButton 由公共组件 Button 和 NormalText 组合而成。

详细代码不在本文中提供,以思路为重。

Card 新建页

整体过程类似于 Decks 页面的构建。主要就是在 View 触发 CardActions.createCard 这一 Action,在 Card 的 Store 中监听以更新数据集合。

Review 交互页

本页面有两种场景,若存在尚未 Review 过的 Card 则显示可选择答案的 Review 页面,否则显示 Review 结果(正确率)。所以 src/components/Review/index.js 里分两种情况返回 UI 结构。

选择答案的 UI 结构,其封装在 ViewCard.js 中,做法类似于之前 Decks 利用 map 高阶函数的方案。Review 这一块稍微难懂一点的是其 Store 里根据录入的卡片构造选项的逻辑,但这其实已不是 React Native 的范围,耐心的多看一会儿就可以懂。

问题与解决方案

Decks 页面不展示模拟数据

我在完成 Decks 页面的展示时,就不等 Create Deck 功能的实现,就开始测试一下页面。比如在 components/Decks/index.js 的 getInitialState 中直接构造几个 Deck 对象。但是并没有展示出来:[

原因在于 Store 发出的消息,导致 View 的 state 里的数据立即被置空。我们可以临时在加个判断,为空就不 setState({decks}) 即可。

Review 结果展示页告警

该页使用公共组件 NormalText 并传递 color 给它,但作者提供的 NormalText 代码里使用的是 View.propTypes.style,应改为 Text.propTypes.style!

原文地址:http://balloonsys.com/blog/2016/10/18/rn-put-it-all-together/

React Native 项目实战-Tamic的更多相关文章

  1. 【腾讯Bugly干货分享】React Native项目实战总结

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 “8小时内拼工作,8小时外拼成长 ...

  2. React Native 项目实战 -- DoubanProject

    引言:本文是我研究react-native时写的一个简单的demo,代码里有详细的注释,好废话不多说,直接上代码. 1.项目目录 2.index.android.js /** * index.andr ...

  3. React Native项目实战

    算是学习React Native的一次项目总结吧,目的还是提高自己. 包含的内容: 1>仿"美团"页面的实现; 2>封装项目中和自己常用的一些组件; 3>学习别人 ...

  4. React Native 项目运行在 Web 浏览器上面

    React Native 的出现,让前端工程师拥有了使用 JavaScript 编写原生 APP 的能力.相比之前的 Web app 来说,对于性能和用户体验提升了非常多. 但是 React Nati ...

  5. react native项目启动需要做的操作

    一.启动: 1.查看端口(默认8081是否被占用) netstat -ano   可以查看所有的进程 2.netstat -ano | findstr "8081"  查看某个端口 ...

  6. React Native 项目整合 CodePush 全然指南

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/y4x5M0nivSrJaY3X92c/article/details/81976844 作者 | 钱 ...

  7. React Native项目集成iOS原生模块

    今天学习一下怎么在React Native项目中集成iOS原生模块,道理和在iOS原生项目中集成React Native模块类似.他们的界面跳转靠的都是iOS原生的UINavigationContro ...

  8. Expo大作战(三)--针对已经开发过react native项目开发人员有针对性的介绍了expo,expo的局限性,开发时项目选型注意点等

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  9. 安装android Studio和运行react native项目(基础篇)

    ANDROID_HOME环境变量 确保ANDROID_HOME环境变量正确地指向了你安装的Android SDK的路径. 打开控制面板 -> 系统和安全 -> 系统 -> 高级系统设 ...

随机推荐

  1. Eureka服务注册中心

    Eureka服务注册中心 最近在研究Spring Cloud,发现其中的组件实在是太多了,真的是头大,只能一块一块看,像盲人摸象一样.要想很短时间内掌握Spring Cloud是不可能的,小编就学习一 ...

  2. nginx location的命中过程

    1 先判断精准命中,立即返回结果并结束解析过程 2 判断普通命中,如果有多个命中,"记录"下"最长"的命中结果(注意:记录但不结束,最长的为准) 3 继续判断正 ...

  3. 浅析java的深拷贝与浅拷贝

    (转自:http://www.cnblogs.com/chenssy/p/3308489.html) 首先来看看浅拷贝和深拷贝的定义: 浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式 ...

  4. 小工具:批量导入导出主机上的docker镜像

    工作需要,将主机上的部分镜像导出为tar文件,放便在其他主机上使用 用python实现了一个批量打包脚本: import re import os import subprocess if __nam ...

  5. 深入理解事件(Event)

    前言 在前一篇文章中讲到了Event 发布与订阅(一) 里面用到了事件来实现一些发布与订阅,当时对事件及其委托理解的还不是太深入,可能在使用上有点捉急.这篇来好好讲讲事件,以及通过一些小DEMO来加深 ...

  6. [Wc2010]重建计划

    Description Input 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案, ...

  7. [HNOI2016]序列

    题目描述 给定长度为n的序列:a1,a2,...,an,记为a[1:n].类似地,a[l:r](1<=l<=r<=N)是指序 列:al,al+1,...,ar-1,ar.若1< ...

  8. ●POJ 1741 Tree

    题链: http://poj.org/problem?id=1741题解: 树上点分治. 入门题,不多说了. 代码: #include<cstdio> #include<cstrin ...

  9. ●BZOJ 4821 [Sdoi2017]相关分析

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4821 题解: 线段树是真的恶心,(也许是我的方法麻烦了一些吧)首先那个式子可以做如下化简: ...

  10. [UOJ UR #2]树上GCD

    来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 看完题目,一般人都能想到 容斥稳了 .这样我们只要统计有多少点对满足gcd是i的倍数. 考虑长链剖分,每次合并的时候,假设我已经求出轻 ...