• Stars
    star
    222
  • Rank 179,123 (Top 4 %)
  • Language
    JavaScript
  • Created almost 9 years ago
  • Updated almost 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

React Native Starter Kit Build Status

使用说明

点击Download ZIP下载压缩包,并在自己工程下解压(建议解压到新git repo的根目录)。

运行npm install 安装所有依赖

V3 更新说明

  1. 最重要的: 使用了mobx,取代之前的redux或emitter + subscribe方案。subscribe仍在少数地方使用。
  2. 增加了在route或component中指定sceneConfig的用法,这样你就不必每次都在route里指定sceneConfig。
  3. form不再使用单独的组件,改为mobx实现。
  4. 将一些整块功能挪到了单独的包中,如react-subscribe, mobx-form-validation,以便于bug修复和更新。
  5. npm test现在用于单元测试,而npm run eslint则用于代码质量检查。

代码规范说明

语法规范参考airbnb的JavaScript代码规范,适应react-native做了一些调整。

运行npm run eslint可以进行代码规范检查。

逻辑模块

  • 逻辑模块基于mobx开发,应按功能进行划分。

  • 全局性的状态(如登录状态等)应作为单例使用,其它的则应该尽可能在页面或者适当的生命周期内部保存和使用。

  • 不要将observable对象保存在组件的state中,应作为成员属性直接使用。

  • 逻辑模块不应过度面向对象, 只有数据(和对数据的操作)应作为class的形式体现。

页面

  • 在pages下放置页面组件. 如果页面数量较多,可以在pages下组织子文件夹,参考页面子路由

  • 每个页面使用routerDecorator来定义自己的path(通常不应/开头)

  • 在src/pages/index.js里import并加入对应的组件.

子路由

  • 如多个页面具有较强关联性,可组织成子路由

  • 在上级路由(如src/pages)中建立子文件夹,如user

  • 在子文件夹下建立index.js, 内容如下:

import Login from './Login';

export default {
  path: 'user',
  childRoutes: [
    Login,
  ].map(v => v.routeConfig || v),
};
  • 建立对应的Login组件,并通过routerDecorator指定地址,譬如@router('login')

  • 在其上一层路由,譬如src/pages/index中,导入并使用该路由

/**
 * Created by tdzl2003 on 6/28/16.
 */

import Splash from './Splash';
import Home from './Home';
import User from './user';     // 添加这一行,引入子路由

export const routeConfig = {
  path: '/',
  childRoutes: [
    Splash,
    Home,
    User,       // 添加这一行,使用子路由
  ].map(v => v.routeConfig || v),
};

  • 最后访问login页面时,地址是包含了每一级路由的,如location: '/user/login'.

事件订阅

请参考react-subscribe的文档和示例代码。

现在只应该用事件订阅去订阅系统事件等内容,逻辑层应尽可能使用mobx绑定。但少数需要的时刻(如token失效后返回登录页) 依然可以使用Subscribe.

表单

请参考mobx-form-validate的文档和示例代码。

样式-主题

  • 不再推荐使用任何的全局样式

  • 一个样式如果在多个页面中被使用(如按钮,表单输入框等),应考虑封装成组件,在组件内部包含对应的样式,以避免样式重复定义

  • 所有重复定义的样式都应当至少被思考一遍,是否要抽象成组件.

  • 较小的组件不应配套.style.js文件,但如果文件过长,还是考虑将样式放入配套的.style.js文件

文件组织

  • 组件所使用的图片资源和子组件建议代码的组织一律遵循"就近"原则。图片等资源应当放在组件同级目录下的assets文件夹中,子组件也建议就近放置。

  • 可被复用的组件(尤其是被多个不在一个目录下的页面引用的组件)应考虑放置在公共的components文件夹中。

对话框

  • 使用Navigator来实现对话框。

  • 对话框类均应包含正确的sceneConfig静态成员。

异步错误捕获

异步请求在逻辑层处理过程应尽可能保证信息无丢失,错误体应被透传至最外层而不经任何修改。

最后在视图层捕获错误并决定对应的显示。

严禁直接在逻辑层弹出Alert或Toast。

TabBar的实现

TabBar采用react-router直接实现,不依赖第三方组件。

导航条控制

导航条自动在每个界面都被包含,导航条如果出现的页面并非路由栈底部,将会自动出现返回按钮。

你可以通过在页面的routeConfig(或通过页面静态成员)的一些属性来控制导航条:

  • hideNavBar: 在此界面下将隐藏导航条
  • title: 控制导航条的标题显示
  • leftNavTitle: 导航条左侧显示的标题,如"返回"等
  • rightNavTitle: 导航条右侧显示的标题,如"筛选"等
  • 更多属性添加中。。

你可以在组件里实现以下两个方法来获取导航条的相关通知:

  • onLeftPressed 当导航条返回按钮或左侧标题被点击的时候调用
  • onRightPressed 当导航条右侧标题被点击的时候调用

加载更多列表

使用PageList作为对应的observable,很容易就可以实现加载更多的列表:

可以修改PageList以适应你的前后端接口方式(包括对isOver的判定)

@route('home')
@observer
export default class Home extends Component {
  @observable
  articleList = new PageList('/article/list');
  
  fetchMore = () => {
    this.articleList.fetch();
  };
  
  renderRow = row => {
    return (
      <ArticleItem data={row} key={row.id} />
    );
  };
  render() {
    return (
      <View style={styles.container}>
        <ListView
          dataSource={this.articleList.dataSource}
          renderRow={this.renderRow}
          onEndReached={this.fetchMore}
        />
      </View>
    );
  }
}