react native

一、移动APP 开发技术选型进化

第一阶段   Native

1.性能优秀

2.开发效率低下,不可跨端

第二阶段    Native H5/Hybrid

1.Hybrid多端运行,解决了开发效率问题

2.性能存在瓶颈

现阶段  Native H5/Hybrid React Native

二、开发进阶-页面性能

页面(Page)切换卡顿问题

页面切换(push)和render同时进行,对复杂页面场景,会有卡顿问题

解决方案:1.调整页面切换动画时间

                 2.使用InteractionManager API页面切换完成,再render


三、开发进阶-统一Storage

统一Storage提供

1.Storage.load(params,callback)

2.Storage.remove(params)

3.Storage.save(parmas)

说明:

Native/RN/H5通用

Save API,params中domain区分不同业务

Save API,params中expires可控制过期时间

Save API,params中isSecret可控制是否加密存储

四、开发进阶-IconFont

Iconfont使用

1.文件大小,可以设置颜色,灵活性高

2.Font文件中每个图标对应一个Unicode码

使用步骤

1.http://iconfont/平台创建下载字体文件

2.导出字体文件,项目/文件命名规则crn_font_xxx,前缀固定;

3.注册字体文件CRNDev.registerIconFont()测试环境使用,生产环境会动态查找注册;

4.设置组件style,fontfamily = 项目/文件名   Note:iconfont项目/文件名不能手动修改

common.js

export default StyleSheet.create({
    commonIcon: {
        fontFamily: 'ct_font_common',
    },
    diyTourIcon: {
        fontFamily: 'crn_font_diytour2'
    },
    diyTourIcon2: {
        fontFamily: 'crn_font_diyTour'
    }
    
})

页面上使用icon引用字体: icon.js

import PropTypes from 'prop-types';
import React, { Component } from 'react';
import {Text,Dimensions} from 'react-native'
import baseStyle,{color} from "../../styles/base/common"

export default class Icon extends Component {
    render() {
        let { size, color,value, style,type } = this.props
        let fontFamily = baseStyle.diyTourIcon
        if(type==='common'){
            fontFamily=baseStyle.commonIcon
        }else if(type==='dp2'){
            fontFamily=baseStyle.diyTourIcon2
        }
        return (
            <Text
                style={[
                    fontFamily,
                    {
                        color,
                        fontSize: size
                    },
                    style
                ]}
            >
            {value}</Text>
        )
    }

}
Icon.propTypes = {
    size: PropTypes.number,
    color: PropTypes.string,
    value: PropTypes.string,
    style: Text.propTypes.style,
}
Icon.defaultProps = {
    size: 20,
    color: color.cBule,
    value:'',
}

开发环境常见问题

1.icon不显示,一般是由于下载的文件名被修改过文件名

生产环境常见问题

1.图标非自己设计的icon,一般是被系统其它unicode占用,到iconfont平台生成新的code即可


五、开发常见问题

A.原因: Native Runtime 和 RN JS 代码API 不一致

解决方案:

1.删除node_modules

2.修改package.json中依赖的相关JS组件版本

3.重装node_modules


B.原因:依赖CRN版本和App版本不一致 0.51 runtime的App运行0.41的Js代码

解决方案:

1.删除node_modules

2.修改package.json中CRN的依赖分支

3.重装node_modules


C.原因:从node_modules查找模块出错

解决方案:

1.npm list |grep react* 查看是否有其他组件使用不同的react版本

2.删除node_modules

3.重启电脑,重新安装node_modules


六、CRN发布

发布流程:

1.创建项目(发布计划),设置代码仓库分支,入口文件,发布版本、频道

2.新增版本,FAT->UAT->生产 环境逐一发布

3.支持灰度发布、暂停发布

4.发布结果查看,支持分APP版本查看下载量、使用量


CRN-Web框架

crn-cli run-patch  替换RN依赖文件

crn-cli pack 本地打包

crn-cli openUrl 在App中打开url

crn-cli example 建立API示例工程

crn默认会依赖常用第三方库 crn-ext提供常用第三方库,业务按需依赖 eg: react-native-swiper

页面路由与跳转

page.push()

page.pop()

page.popToPage()

page.replace()

page.replaceAtIndex()

pop到容器最后一层后直接关闭CRN容器



Android物理键回退:onBackAndroid()


组件和Page生命周期:

componentWillMount           PageWillAppear

componentDidMount            PageDidAppear

componentWillUpdate           PageWillDisappear

componentDidUpdate           PageDidDisappear

componentWillUnMount



CRN页面加载流程

包安装 -> CRN框架代码执行(后台预加载) -> 业务JS -> 代码执行(a.页面渲染 b.初始页面渲染->网络请求->页面渲染)




router.js

import { App,lazyRequire } from '@ctrip/crn';
import pageConfig from './constants/pageConfig';
const DIYIndex = lazyRequire('./containers/diyIndex');
const DPCalendar = lazyRequire('./containers/dpCalendar');
const CityList = lazyRequire('./containers/cityList');
const DPIndex = lazyRequire('./containers/dpIndex');
const Confirm = lazyRequire('./containers/confirm');
const DPConfirm = lazyRequire('./containers/dpConfirm');
const Passenger = lazyRequire('./containers/passenger');
const FlightList = lazyRequire('./modules/flightList/container/flightList');
const HotelDetail = lazyRequire('./containers/hotelDetail/hotelDetail');

const pages = [
    {
        component: DIYIndex,
        name: pageConfig.DIYINDEX.pageName,
        // isInitialPage: true 
    },
    {
        component: DPCalendar,
        name: pageConfig.DPCALENDAR.pageName,
        // isInitialPage: true 
    }, {
        component: CityList,
        name: pageConfig.CITYLIST.pageName,
    },
    {
        component: DPIndex,
        name: pageConfig.DPINDEX.pageName
    }, {
        component: DPConfirm,
        name: pageConfig.DP_CONFIRM,
        // isInitialPage: true
    }, {
        component: Confirm,
        name: pageConfig.SDP_CONFIRM.pageName
    }, {
        component: FlightList,
        name: pageConfig.FLIGHT_LIST.pageName,
        // isInitialPage: true
    },
    {
        component: Passenger,
        name: pageConfig.PASSENGER.pageName,
    }, 
    {
        component: HotelDetail,
        name: pageConfig.HOTEL_DETAIL.pageName,
        isInitialPage: true
    }
];

const navigationBarConfig = {
    hide: true, // 默认为 false
    backgroundColor: "#19A0F0", // 导航栏背景色
};

export default class Router extends App {
    constructor(props) {
        super(props);
        this.init({
            pages,
            navigationBarConfig,
        });
    }
}

index.ios.js

/**
 * Sample Ctrip React Native App
 * http://crn.site.ctripcorp.com/
 * @flow
 *
 * 此处有几点需要注意:
 * 1、必须将AppRegistry.registerComponent写在该文件中, 并且将AppComponent从其他处require进来;
 * 2、必须添加一个module.exports这一句, 发生产包必须这么做;
 */

'use strict';

import {
    AppRegistry
} from 'react-native';

const DIYTOUR = require('./main');

AppRegistry.registerComponent('diytour', () => DIYTOUR);

//Attention: 此处module.exports必须保留
module.exports = DIYTOUR;

index.android.js

/**
 * Sample Ctrip React Native App
 * http://crn.site.ctripcorp.com/
 * @flow
 */

'use strict';

import {
  AppRegistry,
} from 'react-native';

const DIYTOUR = require('./main');
AppRegistry.registerComponent('diytour', () => DIYTOUR);

// Attention: 此处module.exports必须保留
module.exports = DIYTOUR;

main.js

'use strict';

import { CRNDev } from '@ctrip/crn';

import DIYTOUR from './src/app';

// global.console = {
//   timeEnd: ()=>{},
//   time: ()=>{},
//   info: () => {},
//   log: () => {},
//   warn: () => {},
//   debug: () => {},
//   error: () => {},
// };
if (__DEV__) {
  CRNDev.registryIconFont({
    fontList:[
      'http://10.32.228.8:5389/fonts/crn_font_diytour2.ttf',
      'http://10.32.228.8:5389/fonts/crn_font_diyTour.ttf',
    ]
  }, (result) => {
    console.log('ttf文件安装' + (result ? '成功' : '失败'));
  });
}

module.exports = DIYTOUR;

import打包后->require -> JS exe -> Cache Ret -> LazyRequire的使用(LazyRequire加载Page子类,只加载需要的Page)


















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值