React Native 项目实战-Tamic
- 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的更多相关文章
- 【腾讯Bugly干货分享】React Native项目实战总结
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 “8小时内拼工作,8小时外拼成长 ...
- React Native 项目实战 -- DoubanProject
引言:本文是我研究react-native时写的一个简单的demo,代码里有详细的注释,好废话不多说,直接上代码. 1.项目目录 2.index.android.js /** * index.andr ...
- React Native项目实战
算是学习React Native的一次项目总结吧,目的还是提高自己. 包含的内容: 1>仿"美团"页面的实现; 2>封装项目中和自己常用的一些组件; 3>学习别人 ...
- React Native 项目运行在 Web 浏览器上面
React Native 的出现,让前端工程师拥有了使用 JavaScript 编写原生 APP 的能力.相比之前的 Web app 来说,对于性能和用户体验提升了非常多. 但是 React Nati ...
- react native项目启动需要做的操作
一.启动: 1.查看端口(默认8081是否被占用) netstat -ano 可以查看所有的进程 2.netstat -ano | findstr "8081" 查看某个端口 ...
- React Native 项目整合 CodePush 全然指南
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/y4x5M0nivSrJaY3X92c/article/details/81976844 作者 | 钱 ...
- React Native项目集成iOS原生模块
今天学习一下怎么在React Native项目中集成iOS原生模块,道理和在iOS原生项目中集成React Native模块类似.他们的界面跳转靠的都是iOS原生的UINavigationContro ...
- Expo大作战(三)--针对已经开发过react native项目开发人员有针对性的介绍了expo,expo的局限性,开发时项目选型注意点等
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- 安装android Studio和运行react native项目(基础篇)
ANDROID_HOME环境变量 确保ANDROID_HOME环境变量正确地指向了你安装的Android SDK的路径. 打开控制面板 -> 系统和安全 -> 系统 -> 高级系统设 ...
随机推荐
- POJ-3723 Conscription---最大权森林---最小生成树
题目链接: https://vjudge.net/problem/POJ-3723 题目大意: 需要征募女兵N人, 男兵M人. 每征募一个人需要花费10000美元. 带式如果已经征募的人中有一些关系亲 ...
- html标记语言 --文本标记
html标记语言 --文本标记 二.文本标记 1.h1-h6 标题标记,h1最大 2.font 字体设置标记 2.1 size字体大小.<font size="> 取值范围1-7 ...
- Python的字典和JSON
Python的字典和JSON在表现形式上非常相似 #这是Python中的一个字典 dic = { 'str': 'this is a string', 'list': [1, 2, 'a', 'b'] ...
- gradlew在Travis CI没可执行权限 permission denied
问题的来源 我给一个gradlew项目添加Travis CI的时候遇到一个问题,gradlew没有可执行权限.具体错误如下: /home/travis/build.sh: line 45: ./gra ...
- MySQL · 引擎特性 · InnoDB 同步机制
前言 现代操作系统以及硬件基本都支持并发程序,而在并发程序设计中,各个进程或者线程需要对公共变量的访问加以制约,此外,不同的进程或者线程需要协同工作以完成特征的任务,这就需要一套完善的同步机制,在Li ...
- 实验吧_简单的sql注入_1、2、3
简单的sql注入1 看着这个简单的界面,一时间没有特别好的思路,先输入一个1',发生了报错 初步猜测这是一个字符型的注入,他将我们输入的语句直接当成sql语句执行了,按题目的意思后面肯定过滤了很多注入 ...
- Ubuntu 16下安装64位谷歌Chrome浏览器
Ubuntu 16下安装64位谷歌Chrome浏览器 1.将下载源加入到系统的源列表 在终端中,输入以下命令: sudo wget https://repo.fdzh.org/chrome/googl ...
- [APIO 2016]Gap
Description 题库链接 给你一个长度为 \(N\) 的单调递增序列 \(A\) .交互时允许你调用 MinMax(s, t, &mn, &mx) 函数,表示序列元素的值在 \ ...
- CTSC&APIO2017
CTSC Day -1 因为越发感到自己与dalao们之间姿势水平的差距,本来打算再多学些姿势,但被老师叫去做noi,于是花了一两周的时间做完了noi2011~2015,也学到了一些奇怪姿势,还是挺有 ...
- poj3237 树链部分 边权模板
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 7384 Accepted: 2001 Description ...