当前位置: 首页 > 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
  • [LeetCode] Wiggle Sort
  • Apache的基本使用
  • C# 免费离线人脸识别 2.0 Demo
  • Java比较器对数组,集合排序
  • pdf文件如何在线转换为jpg图片
  • PermissionScope Swift4 兼容问题
  • React 快速上手 - 07 前端路由 react-router
  • Redis中的lru算法实现
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 温故知新之javascript面向对象
  • 小程序01:wepy框架整合iview webapp UI
  • 移动端解决方案学习记录
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (十六)Flask之蓝图
  • (十六)一篇文章学会Java的常用API
  • (十三)Maven插件解析运行机制
  • (四) 虚拟摄像头vivi体验
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转)h264中avc和flv数据的解析
  • (转)shell中括号的特殊用法 linux if多条件判断
  • (转)视频码率,帧率和分辨率的联系与区别
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .NET Core 中插件式开发实现
  • .net mvc 获取url中controller和action
  • .NET NPOI导出Excel详解
  • .NET下的多线程编程—1-线程机制概述
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • @AutoConfigurationPackage的使用
  • @Import注解详解
  • [145] 二叉树的后序遍历 js
  • [BZOJ] 2006: [NOI2010]超级钢琴
  • [C++] sqlite3_get_table 的使用
  • [CISCN 2019华东南]Web11