前端和React Native代碼互轉總結

React Native出現的目的本就是「learn once, write anywhere」,Facebook但願人們可以學習一次,處處使用,可是一樣是JS代碼,從前端移植到RN,或者RN移植到前端,卻並無想象的那麼容易。事實上除了語法相同外,還有不少不同的地方,致使咱們無法作到直接copy,如下是我在作遷移代碼的時候,總結的一些經驗css

1 Antd Mobile

Antd Mobile的螞蟻金服開源的一套UI組件,已經實現了前端、iOS、Android的三端統一UI,推薦你們多多使用前端

1.1 Flex

1.1.1 使用Flex的參數

多用direction justify align 屬性,由於某些移動端瀏覽器不支持Flex功能,影響到適配,而antd已經幫我作過了,只是須要咱們採用如下寫法,不然無效 例如:react

Good:git

<Flex  direction="column" align="start" justify="startt">
複製代碼

Bad:(這種寫法並無利用到Flex自己的適配)web

<Flex style={{  
flexDirection: "column",  
backgroundColor: "white",
justifyContent: "flex-start"
}}>
複製代碼

這樣的話,由於前端的兼容性你須要寫不少適配的css代碼,例如npm

{
      display: flex;
      display: -webkit-flex;
      flex-direction: row;
      -webkit-flex-direction: row;
      justify-content: flex-start;
      -webkit-justify-content: flex-start;
      align-items: center;
      -webkit-align-items: center;
}
複製代碼

1.1.2 顯示指定flexDirection

由於某些狀況下Flex沒法使用,例如RN端的Touchable組件只能包裹原生組件,必須用View替代Flex,而View和Flex的默認方向是不同的,所以顯示寫出flexDirection,明確告知方向,方便遷移者改動代碼react-native

Good:瀏覽器

<Flex  direction="column">
     {...}
</Flex>
複製代碼

Bad:(替換成View時候方向會錯)bash

<Flex>
     {...}
</Flex>
複製代碼

1.2 ListView

在RN 0.51版本下,antd的ListView會報錯,仍是使用RN提供的ListView,只須要修改import ListView便可,其餘寫法徹底一致antd

// 不推薦
import { ListView } from "antd-mobile";
// 推薦
import { ListView } from "react-native";
複製代碼

2 代碼規範

2.1 儘可能組件化

某些頁面很複雜,常見的一種寫法是將頁面拆分紅若干模塊,每一個模塊寫一個moduleRender函數,再在render函數裏分別調用,相似如下

Bad:

class SomeComponent extends Component {
      renderSubOne() {
        return <Flex>{...}</Flex>;
      }
      renderSubTwo() {
        return <Flex>{...}</Flex>;
      }
      renderSubThree() {
        return <Flex>{...}</Flex>;
      }
      render() {
         return <Flex>
            {this.renderSubOne()}
            {this.renderSubTwo()}
            {this.renderSubThree()}
          </Flex>
      }
}
複製代碼

Good:

  1. 由於遷移極可能是遷移某一部分,儘可能拆分紅組件遷移起來更靈活
  2. 這種寫法性能更高,分開寫的話每一個組件有本身的生命週期,某個子組件刷新時不會影響父組件
class SomeComponent extends Component {
      render() {
         return <Flex>
            <SubOne />
            <SubTwo />
            <SubThree />
          </Flex>
      }
}
複製代碼

2.2 不要用css

關於樣式的寫法,RN和前端有個顯著的差異 RN:

import { StyleSheet } from "react-native";

const styles = StyleSheet.create({
 someContainer: {
    fontSize:16,
    fontWeight: 'bold',
  },
  ...
})

<Flex style={styles.container} />
複製代碼

前端:

// js 文件
import CSSModules from 'react-css-modules';
...

@CSSModules(styles)
...

<Flex className="someContainer">
複製代碼
// css文件
.someContainer{
      font-size: 16px;
      font-weight: bold;
 }
複製代碼

由上面示例可知

  1. 前端的樣式是藏在css文件內的,遷移起來須要一一去查找
  2. 關鍵字命名不一樣(font-size,fontSize)

而這些不一樣都須要咱們遷移的時候一一手動修改,工做量很大

推薦的寫法,是統一使用RN的寫法:

// 前端js文件
const styles = { // 這裏不須要像RN同樣,使用StyleSheet.create
 someContainer: {
    fontSize:16,
    fontWeight: 'bold',
  },
  ...
}

<div style={styles.container} />
複製代碼

2.3 第三方組件

挑選第三方組件要注意

  1. 儘可能使用原生,或者antd
  2. 儘可能選擇支持前端和移動端的
  3. 儘可能選擇有人維護的
  4. 若是git無人維護或者年代久遠,建議將代碼copy過來,而不是用npm管理,由於RN和React版本更新的緣由,經常須要手動修改部分代碼,才能運行,所以直接copy至工程裏,比較方便

3 差別

有一些差別是前端和RN自然的差別,須要注意

3.1 Image

加載圖片資源在兩端寫法並不同,須要手動修改

前端:

<img style={{ width: 98, height: 82 }} src={nullImg} alt="nullImg" />
複製代碼

RN:

<Image style={{ height: 15, width: 15, marginLeft: 10 }} source={{ uri: 'search3' }} />
複製代碼

3.1.1 RN的Image

須要特別注意一下的是,React Native 0.50.3之後,Image組件再也不能包裹child

<Image> // 0.50.3之後,這種寫法報錯
      {...child...}
</Image>
複製代碼

若是確實須要,只能用絕對位置了

3.2 Text文本

前端渲染文本有多種標籤,divspan等,可是RN端只有一種Text,這在遷移時會帶來很大的工做量,文本散落在各個地方,須要人工一一替換。 推薦使用react-intl,RN端是react-intl-native這個有Yahoo提供的第三方組件,實現了在前端、RN端的統一

Bad:

<div>文本</div>
<span>文本</span>
複製代碼

Good:

<FormattedMessage
    style={styles.valueDesc}
    id="someId"
    defaultMessage={text}
  />
複製代碼

3.3 響應事件

前端:

// 能夠添加在任何標籤上
<div onclick={()=>{}} />
<img onclick={()=>{}} />
複製代碼

RN:

<TouchableHighlight onPress={}>// 只能有一個子元素,且必須是RN原生組件,不能是自定義組件
  <View> // 要用一個View來包裹更多的元素
      {child}
  </View
</TouchableHighlight>
複製代碼

由上可知,點擊事件遷移時,經常須要改動較多的代碼

  1. 增長TouchableHighlight標籤
  2. 原標籤下,若是有多個子標籤,那麼還須要增長View來嵌套,還要注意樣式保持不變
  3. onClick改爲onPress

3.4 路由跳轉

  • 前端使用react-route
  • RN端根據具體狀況會有不一樣選擇,例如react-navigationreact-native-navigation

寫法上會有不一樣,須要遷移者根據具體選擇的庫,手動修改

3.5 PropTypes

PropTypes是React提供的一種類型檢測工具,可是隨着版本的變遷,從React 15.5起,PropTypes被移出了React,造成了一個單獨的庫,若是前端和RN兩邊版本不一致,還有可能須要人工大量修改

// react version < 15.5
import React, { Component, PropTypes } from 'react';

// react version >= 15.5
import React, { Component } from 'react';
import PropTypes from 'prop-types';
複製代碼

3.6 全局變量

前端js代碼的運行環境一般是瀏覽器,瀏覽器自己提供全局變量window,而RN端則沒有,所以不要在前端使用window全局變量,而是要使用導入文件

Bad:

window.someVar = var
複製代碼

Good:

// 新建constants.js文件
const object = {
   website:'http://www.hao123.com',
   name:'好123',
};
export default object;

// 須要使用時導入
import constants from './constansts.js'
<Text>{constants.name}</Text>
複製代碼
相關文章
相關標籤/搜索