当前位置: 首页 > news >正文

前端之React实战:创建跨平台的项目架构

本篇为翻译文章,原文地址这里

React/React Native一个很受欢迎的地方在于它能够在不同平台之间共享业务逻辑,在看完 Desktop, Mobile, and Web app in one project这个项目之后笔者就开始思考应该如何组织项目结构,能够使其在web、desktop(Electron)以及mobile应用之间尽可能地共用相同的代码基础,并且保证能在以后的项目中扩展到其他平台。

文件索引

首先需要认识到在mobile项目与web/desktop项目中最大的代码区别在render()函数中,换言之,我们所需要做的工作就是将render函数抽象出来,以允许具体平台的工程可以使用正确的代码。

要做到这一点,最简单的方式就是利用React Native的一个内部特性,即在使用import/require导入文件时:

import File from './File';  

React Native的打包器会首先寻找 File.<platform>.js文件,然后再去寻找File.js。这就允许我们将Android平台的代码放置到 File.android.js, iOS 的放入到File.ios.js, 以及Web平台的代码放入到 File.js, 而不需要改变导入的声明 ./File

Render独立于Component

这种方式适合于可以在多个平台之间共享复杂状态与逻辑代码的情况下,当然,在该示例中有点过于复杂了。不过笔者认为在实际项目中的作用还是不言自明的。

基础的组件如下所示:

class Hello extends Component {  
    constructor(props) {
       super(props);
    }
    render() {
        // Code to render a container with 
        // "Hello, {props.name}" inside of it
    }
}

在web项目中,Render函数如下所示:

render() {  
    return (<div>Hello, {this.props.name}</div>);
}

而在移动端项目中,Render函数可能如下所示:

render() {  
    return (<View>
        <Text>Hello, {this.props.name}</text>
    </View>);
}

那么整个项目的结构如下所示:

- index.js
- index.ios.js
- index.android.js
- src/
-- Hello.js
-- HelloRender.js
-- HelloRender.android.js

接下来将各个独立的渲染函数和它们的依赖放置到各自的文件中:

// HelloRender.js
import React from 'react';

export default function (props) {  
    // we would like a pure function, for easy testing
    return (<div>Hello, {props.name}</div>);
}

// HelloRender.android.js
import React, {View, Text} from 'react-native';

export default function (props) {  
    return (<View>
        <Text>Hello, {props.name}</text>
    </View>);
}

最终在我们的Hello.js文件中:

// This will import our platform-specific render function
import Render from './HelloRender';

class Hello extends Component {  
    constructor(props) {
        super(props);
    }

    render() {
        // Now we call our render function,
        // bound to the context of our component
        // In this case we're only using component props,
        // but later we may desire to access the state or
        // other methods on the component.
        return Render.call(this, this.props, this.state);
    }
}

注意,虽然我们是针对不同平台使用了不同的渲染函数,但是还是可以共享很多的逻辑控制代码。

Component与模块冲突

上文中一直没有提及一件事,就是应该在哪边引入React / React Native提供的官方的组件,譬如通用的Component这个类。在最新的React v0.14中是分成了react与react-dom两个部分,它的设计思想在于通常的应用只要导入react的模块即可,而在特殊需要的时候可以选择性地导入react-native的模块,不过笔者在自己的试验中没发现这样的解决方法,因此还是决定用类似于上文提及的抽象render函数的方法。我们需要创建两个新的文件:

- index.js
- index.android.js
- src/
-- Component.js
-- Component.android.js
-- Hello.js
-- HelloRender.js
-- HelloRender.android.js

接下来,我们需要根据平台正确地导入不同的组件,即在新文件中:

// Component.js
export {Component} from 'react';  

// Component.android.js
export {Component} from 'react-native';  

最后,在我们的Hello.js这个统一的文件中:

// import platform-specific component class
import {Component} from './Component';

class Hello extends Component ...  

好了,到这里一个完整的跨平台的构建应该是完成了。

相关文章:

  • 驱动的加载与卸载例程(C++/C)
  • 寻找
  • Apache 文件根目录设置修改方法 (Document Root)
  • UIView之【UIViewContentMode】
  • Oracle 错误总结及问题解决 ORA
  • android之intent显式,显式学习
  • Daily Scrum - 11/19
  • 标签禁用之readonly和disabled
  • 利用shell实现批量添加用户
  • 关机--小程序
  • Elaticsearch REST API常用技巧
  • eclipse控制台乱码的解决方法
  • QT信号槽机制
  • Nginx 配置详解
  • Monitor traffic to localhost from IE or .NET
  • Angular Elements 及其运作原理
  • CSS盒模型深入
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • ES10 特性的完整指南
  • gf框架之分页模块(五) - 自定义分页
  • HashMap ConcurrentHashMap
  • JavaScript HTML DOM
  • Python爬虫--- 1.3 BS4库的解析器
  • Tornado学习笔记(1)
  • ucore操作系统实验笔记 - 重新理解中断
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 配置 PM2 实现代码自动发布
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • $(function(){})与(function($){....})(jQuery)的区别
  • ${ }的特别功能
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (八)Spring源码解析:Spring MVC
  • (二)pulsar安装在独立的docker中,python测试
  • (分类)KNN算法- 参数调优
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (转)ABI是什么
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET Core中Emit的使用
  • .net MySql
  • .NET Project Open Day(2011.11.13)
  • .NET WebClient 类下载部分文件会错误?可能是解压缩的锅
  • .Net Web项目创建比较不错的参考文章
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .NET开源快速、强大、免费的电子表格组件
  • .sh
  • :中兴通讯为何成功
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • @RequestBody的使用
  • @开发者,一文搞懂什么是 C# 计时器!