美文网首页
React Native 初体验

React Native 初体验

作者: 契约工程师 | 来源:发表于2017-08-23 15:48 被阅读0次

1. 安装环境,仅以mac为例

  • 如果需要iOS与Android同时开发运行,必须使用装有macOS的电脑,请知悉

1.1 首先安装homebrew(mac系统下的包管理器)

  • 首先查看是否安装了homebrew 输入: brew -v

  • 如果没有安装,需要安装
    输入: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    如果不是管理员账户,会遇到权限问题

    输入: sudo chown -R `whoami` /usr/local

1.2 安装node.js

  • 使用homebrew 安装 node 输入: brew install node

  • 修改源,或者科学上网法(翻墙)
    npm config set registry https://registry.npm.taobao.org --global
    npm config set disturl https://npm.taobao.org/dist --global

  • 注意: 合理可以使用cnpm 来代替npm提高运行效率

1.3 安装yarn(代替npm加快node module下载速度)以及react-native-cli(RN的编译打包工具)

  • 输入代码 npm install -g yarn react-native-cli
  • 修改源
    yarn config set registry https://registry.npm.taobao.org --global
    yarn config set disturl https://npm.taobao.org/dist --global

1.4 推荐安装watchman, Flow 不推荐!

watchman 能够实时刷新,所见即所得!

1.5 安装Sublime 开发 以及 如何使用package control安装IDE

  • 首先按照https://packagecontrol.io/installation#st3 安装package control,注意自己sublime的版本,
  • 安装成功后,到preference 里面的package control 中输入install package,等候一小会儿,
  • loading结束后出现输入框,输入需要安装的插件

推荐使用的插件 : ReactJS Emmet Terminal react-native-snippets


2 纯RN语法项目,以项目名称MyApp为例

2.1 创建项目,初始化npm,node.js服务器配置等一系列操作

终端 运行 react-native init MyApp --version 0.44.3

  • 注意事项,我们这里指定版本0.44.3,如果没有版本,运行时会提示错误 Print: Entry, ":CFBundleIdentifier", Does Not Exist 或者 Command /bin/sh failed with exit code 1 让人难以理解,主要是新版本没有有效的支持,出现这两个错误,请重新创建项目!!!

  • 具体原因已经发现!!!! ,查看package.json 的dependencies 依赖中, react 依赖的版本是alpha 版本,我们需要替换成稳定版本!!

2.2 到MyApp的目录下,直接运行

cd MyApp && react-native run-ios

2.3 简单修改和运行的大致步骤

  • RN 程序启动在ios工程中的 main.m中,循环调用appDelegate 代理,代理中某些方法会一直执行,某些方法只会执行一次
  • appDelegate 中- (BOOL)application: didFinishLaunchingWithOptions:是程序启动的入口,仅仅调用一次 . OC代码通过寻找到js文件里的模块具体加载,所以OC调用的js文件名称必须与文件夹里的文件名称一致,模块名称必须和js文件里注册模块名保持一致
  • js文件中最后一句代码是注册,即注册js中的某个模块,执行js中的某个类,告诉OC 该运行哪个模块
  • 简单修改下

AppDelegate中修改

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"myAPP" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"module1"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
                                                   

JS文件中修改

AppRegistry.registerComponent('module1', () => clas1);

export default class clas1 extends Component

3 iOS向现有的项目集成RN代码

创建工程,并且将工程纳入pod 管理下,

3.1 在工程的根目录下创建文件夹,随意取名,比如RNComponent

  • 进入RNComponent目录,创建package.json文件

名称,版本和依赖会变化,注意!

{
  "name": "appTest",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "react": "16.0.0-alpha.6",
    "react-native": "0.44.3"
  }
}

  • 安装node 依赖包库 推荐npm install,如果错误试试cnpm install,需要一段时间,耐心等待
  • 在package.json同级目录下,创建一个文件,比如index.ios.js

内容为要创建的页面的内容,获取原生页面传过来的score,并且显示

'use strict';

import React from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

class RNHighScores extends React.Component {
  render() {
    var contents = this.props["scores"].map(
      score => <Text key={score.name}>{score.name}:{score.value}{"\n"}</Text>
    );
    return (
      <View style={styles.container}>
        <Text style={styles.highScoresTitle}>
          2048 High Scores!
        </Text>

        <Text style={styles.highScoresTitle}>
          30000000
        </Text>

        <Text style={styles.scores}>    
          {contents}
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF',
  },
  highScoresTitle: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  scores: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

// 整体js模块的名称,注册名称是ssss
AppRegistry.registerComponent('ssss', () => RNHighScores);

3.2 原生工程的集成

  • podfile 中 加入下面的依赖库,注意依赖的路径选择,path是实际路径

  # 'node_modules'目录一般位于根目录中
  # 但是如果你的结构不同,那你就要根据实际路径修改下面的`:path`
  pod 'React', :path => './RNComponent/node_modules/react-native', :subspecs => [
  'Core',
#  'CxxBridge', # 如果RN版本 >= 0.47则加入此行
  'DevSupport', # 如果RN版本 >= 0.43,则需要加入此行才能开启开发者菜单
  'RCTText',
  'RCTNetwork',
  'RCTWebSocket', # 这个模块是用于调试功能的
  # 在这里继续添加你所需要的模块
  
  'ART',
  'RCTActionSheet',
  'RCTAdSupport',
  'RCTGeolocation',
  'RCTImage',
  'RCTPushNotification',
  'RCTSettings',
  'RCTVibration',
  'RCTLinkingIOS',
  ]
  
  # 如果你的RN版本 >= 0.42.0,请加入下面这行
  pod "Yoga", :path => "./RNComponent/node_modules/react-native/ReactCommon/yoga"

  • 安装依赖

pod install

3.3 RN的js代码最终替代的是MVC中的View,所以我们用view来接收RN的代码


func doSome()  {
        
        // 这里如果是要求真机运行,请务必将真机的ip修改到这里来,如果是127.0.0.1或者localhost ,只能模拟器访问 , 平台是ios,开发模式下
        let jsPath = URL(string: "http://172.29.164.9:8081/index.ios.bundle?platform=ios&dev=true")
        
        // 传递的数据,以字典形式传递
        let metaData: Dictionary = ["scores":
            [
                ["name":"william", "value":"42"],
                ["name":"ssss", "value":"10"]
            ]
        ]
        
        // 这里的ssss是js中注册的名称,会找到index.ios.js中的ssss模块
        let rootView = RCTRootView(bundleURL: jsPath, moduleName: "ssss", initialProperties: metaData, launchOptions: nil)
        
        // 设置view
        let vc = UIViewController()
        vc.view = rootView
        self.present(vc, animated: true, completion: nil)
        
}

3.4 启动npm服务,运行项目

npm start

3.5 运行项目即可

  • 可以通过修改index.ios.js 来改变页面,模拟器上使用command + R 来重新编译加载RN 的内容, 真机使用摇一摇呼出开发选项,选择reload即可
  • 如果运行时,工程有长连接的保活 打印,有时候会感觉很烦

找到edit scheme 中的envirment variables ,添加键值对 OS_ACTIVITY_MODE disable

3.6 但是目前有一个问题,一旦远程npm没有启动,就会导致连接失败

如何摆脱node服务器?

  • 在json.package 目录下创建release_ios 文件夹

  • 然后通过react-natice 命令创建 main.jsbunlde文件夹

react-native bundle --entry-file index.ios.js --platform ios --dev false --bundle-output release_ios/main.jsbundle --assets-dest release_ios/

  • 生成的文件夹中可能有main.jsbundle,main.jsbundle.meta,asset等,将main.jsbundle 以及asset拖到工程的目录中

这里遇到一个BUG,就是swift4.0 如果直接拖到目录,然后拖到工程目录,会导致找不到文件...,只能直接拖到工程目录中!!

还有个问题,如果遇到多个js文件,那怎么批量处理,待续

4 语法分析

4.1 JS 语法

// 从'react'中引入组件
import React, {
  Component,
} from 'react';

// 从react-native 中引入各个单一的组件名称
import {
  TabBarIOS, 
  NavigatorIOS 
} from 'react-native';

//对工程扩展组件
class App extends Component {
  render() {
    return (
      <TabBarIOS>
        <TabBarIOS.Item title="React Native" selected={true}>
          <NavigatorIOS initialRoute={{ title: 'React Native' }} />
        </TabBarIOS.Item>
      </TabBarIOS>
    );
  }
}

几个关键字:export,default,extends关键字

4.2 样式表

var styles = StyleSheet.create({
  row: { flexDirection: 'row', margin: 40 },
  image: { width: 40, height: 40, marginRight: 10 },
  text: { flex: 1, justifyContent: 'center'},
  title: { fontSize: 11, fontWeight: 'bold' },
  subtitle: { fontSize: 10 },
});

这里通过创建一个变量 的样式类 来管理所有的样式

4.3 最重要的,入口文件必须要加,其他文件不必加

// 注意,这里用引号括起来的'HelloWorldApp'必须和你init创建的项目名一致
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);

程序入口文件必须要进行注册,ios才能识别到这个js文件,从这个入口进

5. 技巧

5.1 使用导航控制器以及tab切换控制器

参照 http://www.jianshu.com/p/7d435e199c96

  • 修改8081 端口,有时候8081被占用等
    • (1)启动项目时react-native start --port 8083
    • (2) 手动修改项目下的node_modules\react-native\local-cli\server\server.js下的方法server.js文件,default:8081 改掉
    • (3) lsof -n -i4TCP:8081 查找到占用8081的应用的pid, kill -9 pid 杀死应用

6. 遇到的BUG

前言: 解决BUG说实话还是Stack overflow 靠谱,其他都一般

React Native 真是一堆坑,至少中文网站上一堆坑

  • 如果xxx文件找不到,或者输入npm xxx save 之后报错, npm install npm 是重新下载node_module文件依赖

  • 使用npm xxx save 下载某些新的组件报错? npm 5 貌似有很大的问题!,换成yarn install xxx 试试...如果npm下载之后发现什么都没干就直接报错了??因为npm5 这个坑货下一个删一个,把之前有用的给删了,请先npm install ,然后改用 yarn install xxx

  • 不想在xcode 里面一直提示__nw_connection_get_connected_socket_block_invoke XX Connection has no connected handler ,在edit scheme 里面找到environment variables 设置key 是 OS_ACTIVITY_MODE ,value 是 disable

  • 模拟器运行过程中,突然 ⌘ + R 没反应了!!, 但是command + 1有反应,原因是我不小心按了shift ⌘ + K ,关闭了键盘!!

  • 自定义模块,但是每次运行都会报错Expected a component class got [objesc Object],解决方法,所有的自定义组件首字母都必须大写...

  • 出现RCTFatal 是语法错误了,一般是少些() ; {} 等

  • 单独说一次! 下载安装新的组件时,不要使用npm ,报错不说,还一堆问题,使用yarn add xxx 例如: yarn add react-navigation

  • 使用最新的react-navigation 中的StackNavigator ,提示错误:Route 'xxx' should declare a screen, for example: import xxx ... 这种错误,明明写了,但是要我声明screen,原因是因为调用顺序的问题,需要把定义的screen 放在代码最前面....网上某些'大神'真是够了,废话连篇,不讲重点

6. 使用优缺点介绍

优点 :

  • 方便前端人员快速构建APP
  • RN 在一套代码,多个领域上一直在改进,以后安卓iOS 可以做大绝大多数通用
  • RN 运行效率和iOS 原生相差无几,运行流畅

缺点 :

  • 学习成本高
  • 发布还是需要了解iOS发布知识,依赖于Xcode
  • 不适合复杂需求下的开发
  • 有时会有莫名其妙的BUG
  • 解决问题困难,提示有限
  • App性能损耗,内存占用过大,内部运行了JavaScriptCore 造成的

总结 : 如果是一线开发人员作为附加技能来说,收益是极高的,但是如果作为主职就会有很多局限性.无论是RN还是swift 或者kotlin,未来的方向是增加通用性,swift 开发服务器,swift 开发Android也有人在研究,swift web开发也已经提出.

其他人出现的错误集锦1,感谢作者

其他人出现的错误集锦2,感谢作者

最后的总结部分,对于刚接触的人很友好

官方文档

相关文章

  • React Native For Android初体验

    React Native For Android初体验 @author ASCE1885的 Github 简书 ...

  • react-native 之创建项目(三)

    react-native 官方demo 初体验 [git clone https://github.com/fac...

  • React-Native初体验

    React-Native 初体验 废话不多说先上DEMO地址 环境安装(MAC) brew install nod...

  • React-Native初体验四(window下实现登录界面)

    这篇文章是居于reactNativeTest项目的,要是没有看过之前的文章请先看React-Native初体验一 ...

  • React Native初体验

    混合开发一直都比较想接触的技术,所以这几天就学习了下React Native的配置及JavaScript的基础,体...

  • React Native 初体验

    1. 安装环境,仅以mac为例 如果需要iOS与Android同时开发运行,必须使用装有macOS的电脑,请知悉 ...

  • React Native 初体验

    2015年9月底开始正式接触React native,公司的ios团队用它写了一个安卓项目之后,到上周,公司彻底停...

  • React Native初体验

    互联网发展至今,经历了几个划时代的产物,2000年前后, 新浪、搜狐作为中国第一代互联网的门户席卷了中国大地;20...

  • React Native初体验

    这一个月内,除去枸杞花鸟岛旅游的几天,其余时间都在搞RN,体会良多,在此总结一下 1.环境搭建 运行环境:Node...

  • react native 初体验

    1.cmd + d 开启菜单2.cmd + d 再打开 debug 模式 右上角氵--> 更多工具 --> 开发...

网友评论

      本文标题:React Native 初体验

      本文链接:https://www.haomeiwen.com/subject/ozwkdxtx.html