在现有App项目中使用React-Native(译)

2252 查看

在现有App项目中使用React-Native(译)

原文地址

对于大部分开发者来说, React-Native是有风险的, 所以先在已有项目里, 小规模的使用, 是一个可接受的更稳妥的方案. 这也是问什么翻译了这篇文档.

没有使用Reactive Native的旧项目, 加入React Native很简单, 使用CocoaPods就可以了. 这在一定程度上得益于React Native只想做MVC中的V, 对你已经使用的其他技术栈没什么假设.

依赖的软件

  • CocoaPods 使用gem install cocoapods安装
  • io.js
    • 按照nvm安装文档安装nvm. 之后运行:
      nvm install iojs-v2 && nvm alias default iojs-v2安装最新的io.js兼容版本,并设置你的终端,这样当你输入node就会执行io.js. 使用nvm可以安装多个版本的Node和io.js, 并且方便的在各个版本之间切换.

      使用CocoaPods安装React Native

      CocoaPods是iOS/Mac开发中常用的一个包管理工具,下载和安装React Native要用到它. 如果你还没有安装CocoaPods, 参照这个教程

搞定CocoaPods之后, 向Podfile文件里加入下面的内容(如果没有Podfile文件,在项目的根目录下创建一个).

pod 'React'
pod 'React/RCTText'

在你的项目里增加想用的subspecs

记得安装你需要的subspecs, 如果不加入React/RCTText, 是不能使用<Text>元素的.
然后安装你的pods
$ pod install

创建你的React Native App

React Native App分两部分:

  1. Javascript文件: 包含你实际React NativeApp和其他组件.
  2. Objective-C封装: 加载脚本文件并显示和管理React Native组件.
    第一步, 为app的React代码创建一个目录, 创建index.ios.js

    $ mkdir ReactComponent
    $ touch ReactComponent/index.ios.js

复制下面的代码,粘贴到index.ios.js - 它是一个骨架React Native app

'use strict';

var React = require('react-native');
var {
  Text,
  View
} = React;

var styles = React.StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'red'
  }
});

class SimpleApp extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>This is a simple application.</Text>
      </View>
    )
  }
}
React.AppRegistry.registerComponent('SimpleApp', () => SimpleApp);

SimpleApp是模块的名字, 后面会用到.

将容器视图加到你的App里

使用一个View作为React Native的容器, 只要是UIView的子类就可以.


容器视图示例

为了代码干净一些, 创建一个UIView的子类ReactView.

// ReactView.h 

#import <UIKit/UIKit.h>
@interface ReactView : UIView
@end

在管理这个视图控制器里, 加入这个视图.

// ViewController.m

@interface ViewController ()
@property (weak, nonatomic) IBOutlet ReactView *reactView;
@end

这里为了简化, 禁用了AutoLayout. 在实际的项目里, 你应该打开AutoLayout并且设置好约束.

将RCTRootView 加入容器View

下面将是最有趣的部分, 我们将创建RCTRootView, React Native app就住在里面.

在ReactView.m里, 我们首先需要利用你的index.ios.bundle的URI来初始化你的RCTRootView. index.ios.bundle将被React Native打包器将创建, 并由服务器提供.

NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"];
// 为了应用, `NSURL` 也可以指向一个本地磁盘的文件:
//
//   NSURL *jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
//
// 要生成url对应的文件, 可以使用下面的命令
//
//   curl http://localhost:8081/index.ios.bundle -o main.jsbundle
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                    moduleName: @"SimpleApp"
                                                 launchOptions:nil];

然后将它作为子视图加入ReactView

[self addSubview:rootView];
rootView.frame = self.bounds;

启动开发服务器

在根目录下, 启动React Native 开发服务器.

(JS_DIR=`pwd`/ReactComponent;cd Pods/React;npm run start -- --root $JS_DIR)

这个命令会启动React Native 的开发服务器并编译我们的脚本. —root选项指示React Native应用的根, 就是包含了index.ios.js文件的目录.

运行中的服务器会打包出index.ios.bundle文件, 通过http://localhost:8081/index.ios.bundle.可以访问到.

编译和运行

现在编译和运行你的应用, 你会看到你的React Native运行再ReactView里面.


示例

也可以从模拟器中实时加载! 你拥有了一个简单的React组件, 完全封装在Objective-C的 UIView的子类后面.

总结

在这种情况下, 当RCTRootView初始化, 它将尝试下载,解析并运行脚本文件. 这就是说你只需要实现RCTRootView的容器视图或者控制器.RCTRootView负责渲染你的React组件.

示例的完整的源代码再这里