react-native项目结构介绍

基于雨点儿网,分享react-native开发android app的方法。
上篇文章《零基础用react-native开发android app》介绍了RN(react-native)的一些基本概念以及开发流程,这篇文章主要结合个人开源项目raindrop-app跟你们交流下我本身的代码组织以及开发过程当中遇到的一些问题。css

代码组织:

目录结构:

.
├── components    //组成应用的各个组件
│   ├── Routers.android.js     //每一个组件若实现不同,分为android的实现和ios的实现。
│   ├── Routers.ios.js
│   ├── common     //公共组件
│   ├── issues        //议题页面
│   ├── navigation  //导航组件,android用侧边栏,ios准备用tab
│   └── project      //项目页面
└── network    //网络服务
    └── DataService.js
  1. 我本身的代码所有放在src目录下,这样写代码过程当中搜索啊什么操做比较方便,从逻辑上也比较清晰。html

  2. react的应用,是用自定义组件或原生组件层层嵌套而成的。所以我将整个应用划分为组件部分(组成各个页面)和一些其余服务(目前比较简单,只抽象出发get请求的网络服务)。react

  3. components内,根据本身的业务逻辑进行抽象,把整个应用划分为层层嵌套的组件,目录结构的组织形式基本就是我页面的组织形式。若是有一些比较通用的功能,能够提取成公共组件,我放在common目录下。android

  4. 每一个组件若是ios和android的实现不太同样,则建立两个文件,如Routers.android.jsRouters.ios.jsios

基本逻辑:

  1. 根组件:
    我定义了一个Routers组件,做为整个app的根组件。Router组件实际上包装的官方的Navigator组件,主要做用:git

    • 负责整个app的全部路由,当使用navigator去跳转路由时,会最终进入renderScene函数来渲染不一样的页面。github

    • 提供了默认router,整个程序启动时,默认加载页面ProjectListweb

  2. 各个页面:不一样路由对应不一样的页面,如RoutersrenderScene函数中,每一个if分支是一个页面。这些页面实际上就是一个个导出的组件。好比ProjectList组件是用来作项目列表的,但他自身又包含了一个用来渲染每一个项目单元格的projectCell组件。如此,全部组件都是对上层呈现成一个统一的组件接口,对下层本身去组装多个不一样组件,最终造成一个模块化的统一的app。chrome

  3. 组件之间的关联:
    组件之间常常会发生关联。我本身用到了如下状况:segmentfault

    • 父改变子:

      • 子经过state对外提供接口,父能够经过setState去改变子的状态,并让子从新渲染。state是React的一个很重要的概念。在组件上能够设一些属性,这些属性都有一个初始状态,而后用户的操做产生交互,只要是用setState去触发这个组件状态变化,则会触发这个组件从新渲染 UI 。

      • 父直接调用子导出的方法,好比官方组件DrawerLayoutAndroid提供的openDrawer方法。可使用react的refs机制去调用。好比我在NavTab组件的openNavDrawer函数中,以this.refs['drawer'].openDrawer();这样的函数方式去调用。那么如何像这种方式导出本身的方法供父组件直接以函数方式调用?注意导出的方法必须是做为类方法就能够了,好比openNavDrawer这个函数就是导出给父用的。

    • 子调用父:
      这其实有点相似是反向依赖的设计模式。就是子提供触发回调的接口,可是到底是触发后执行什么,子并不关心。好比我封装的NavToolbar(就是不少界面上面的工具条)组件的onClicked方法。

    • 不少地方的按钮都是返回上一级。
      <NavToolbar ... onClicked={() => {this.props.nav.pop();}} />
      可是最底层的几个界面上的按钮,换成了弹出侧面导航条,以供切换。
      <NavToolbar ... onClicked={this.onToolbarClicked} />
      对于这种状况,导航条要想抽象成公共的组件,他就不能依赖于他的父到底是哪一个界面。触发的具体动做就须要经过回调注入进来,这时就用这种方式。
    • 兄弟关系:
      在共同的父中组合上面两种状况就能够了。好比ProjectList.android.js

    • onToolbarClicked:  function (){
        this.refs['navTab'].openNavDrawer();
      },
      <NavTab ref='navTab' nav={this.props.nav}>
        <NavToolbar icon={"ic_menu_white"} title={'项目'} onClicked={this.onToolbarClicked} />
        {content}
      </NavTab>
    • 其余状况:
      参考这篇文章,不过目前我还没用到这种毫无关系的事件触发,因此还没有研究。

调试

  1. chrome调试:
    安装react dev的chrome官方插件。在手机上设置host的ip,点击start chrome debugging。 chrome会自动跳转到调试地址,在浏览器上打开调试窗口,会发现里面多了一个react页签。

  2. inspect元素:
    在模拟器中打开inspect element面板,点击模拟器中的元素,chrome会跳转到对应dom。

  3. 槽点:

    • 在浏览器改动css后,模拟器的布局不跟着更新。注意每一个dom都有个RN的包裹,须要更改这个以RCT开头的包裹元素。参考issue

    • 浏览器的dom和手机上的元素位置对不许确。我有时会分不清哪一个dom对应我屏幕哪一块。

    • 调试常常失效,调试窗口的react页签动不动就找不到了,我大部分时候是直接改代码,在模拟器看效果的。

遇到的坑:

  1. 模拟器中的程序常常崩溃,代码语法有低级错误,一但reload js,程序就有很大几率崩溃,须要react-native run-android从新开始。

  2. 换工程运行项目,react-native run-android 前最好关下后台,不然两个项目会互相影响。

  3. 出错提示很不完善。
    好比有时我会将<View>误写成<view>,或者忘记关闭标签。而这些低级错误,RN里面每每会很是难排除,提示每每都很奇怪,我都是靠走读代码发现。
    好比有一次,我看了ECMAScript 6 Features的语法后,将DataServicevar SERVER = 'http://www.yudianer.com/api';这句改为了const SERVER = 'http://www.yudianer.com/api';,当时没发现什么问题。但后面发现了奇怪的问题,只有在浏览器调试的时候,app才能正常运行,不然什么也不显示,并且没有任何提示。最后打包运行无数次都没反应,只能一点一点注释代码排除,才发现是我用了ECMAScript 6 Features,却没有配置。。。

  4. RN的有些组件有些限制,每每是后知后觉。例如:

    • DrawerLayoutAndroid这个组件外面不能再包一个<View></View>。若是你不幸这么作了,会整个页面不显示了,而没有任何提示。。。

    • 若是ListView包在一个View中,那么外面这个View须要设置style={flex: 1}。不然ListView将不能滚动。

    • 当遇到这种问题,最好去google一下,或去github看下有没有相似的议题。实在不行就经过注释代码的方法排除。

  5. JSX的语法常常搞错,跟通常的模板语言不太同样。好比:

renderProject: function(project){
    return(
      <ProjectCell
        onSelect={() => this.selectProject(project)}
        project={project}/>
    );
  },

我会常常忘记这是个函数,而直接写成:

renderProject: function(project){
      <ProjectCell
        onSelect={() => this.selectProject(project)}
        project={project}/>
  },

这看上去没什么,问题是这种相似错误的提示很奇怪,很差定位。

总结:

RN在android上确实不太完善,调试工具,错误提示,文档等都不是很友好。但去学习下仍是挺酷的,并且在facebook竭尽全力的推进,相信会愈来愈完善的。

相关文章
相关标签/搜索