React的移動端和PC端生態圈的使用匯總

clipboard.png

對於一項技術,咱們不能停留在五分鐘狀態,特別喜歡一句話,用什麼方式繪製UI界面一點不重要,重要的是底層的思惟,解決問題和優化的思路。

因爲React的生態極爲龐大,本文內容部分來自一些別人的彙總,至於原文只要仍是能找到的,我都會貼上地址,謝謝前期貢獻的做者,若是有沒有被彙總到的,歡迎在下面補充。

生態圈:

React官方推薦超大型項目使用的TypeScript

  • 爲何要把TypeScript放在第一位,由於TypeScript在構建超大型應用時,多人協做能夠極大的加快工做效率,特別是先後端交互特別多,業務狀況特別複雜的情況下(好比IM),它的優點就凸顯出來了。可是在一些中小型項目中,優點並非那麼的明顯。(好比作完項目跑路後期不迭代這種)

clipboard.png

  • TypeScript並非一個新語言,能夠簡單的認爲 TS= js + Type.它只是一個javascript的超集,目前更新速度也是很是快,

clipboard.png

  • 我的建議,在Node.js開發和React native以及大型React中使用TypeScript
  • 在下載官方的react腳手架中,包含了一個第三方的ts建立腳手架的命令javascript

    • Create React App 中使用 TypeScript
    • Create React App 內置了對 ·TypeScript` 的支持。
    • 須要建立一個使用 TypeScript 的新項目,在終端運行:
    • npx create-react-app my-app --typescript
interface IState {
        collapsed?: boolean,
    }
    
    interface IProps {
        props?: string | Function
    }
    constructor(props: IState) {
        super(props)
    }
    flag :number = 123
    componentDidMount() {
        const result = this.FunctionTest()
    }
    FunctionTest():Promise<number|string|object>{
        return Promise.resolve(false)
    }
  • TypeScript寫起來代碼量會多一些,可是對於參數類型,返回類型,一眼明瞭,擁有靜態類型檢查,若是有問題,在編寫代碼時候就能夠知道。
補充一點,如今 TS的生態已經足夠適應開發,像通常的 webpack插件都有了 typescript的文件支持,固然,並非全部的第三包都支持 ts.在技術選型的時候就要考慮清楚這點,不然就會多作不少事情。

狀態統一集中管理,redux,mbox,redux-sage,dva等開源庫

  • 先看看原始的react數據管理

clipboard.png

組件間數據的傳遞,依靠 props,狀態數據提高等完成,可是對於跨層級的組件間數據傳遞,就不那麼友好了,尤爲是大型項目後期的迭代維護
  • 再說說被人吐槽,可是它的單向數據流思想不得不願定的redux.

clipboard.png

  • Reduxcss

    • 狀態及頁面邏輯從 <App/>裏面抽取出來, 成爲獨立的 store, 頁面邏輯就是 reducer
    • <TodoList/> 及<AddTodoBtn/>都是 Pure Component, 經過 connect 方法能夠很方便地給它倆加一層 wrapper 從而創建起與 store 的聯繫: 能夠經過 dispatch 向 store 注入 action, 促使 store 的狀態進行變化, 同時又訂閱了 store 的狀態變化, 一旦狀態有變, 被 connect 的組件也隨之刷新
    • 使用 dispatch store 發送 action 的這個過程是能夠被攔截的, 天然而然地就能夠在這裏增長各類 Middleware, 實現各類自定義功能, eg: logging
    • 這樣一來, 各個部分各司其職, 耦合度更低, 複用度更高, 擴展性更好
在面試的時候,我以爲若是能夠手寫一個 redux庫,而且說清楚單向數據流的思惟,是一個加分項。
  • 最終推薦使用dva,感謝前輩的開源,解放了咱們

clipboard.png

  • dvahtml

    • 正如 Dva 官網所言, Dva 是基於 React + Redux + Saga 的最佳實踐沉澱, 作了 3 件很重要的事情, 大大提高了編碼體驗
// 一個dva的模塊文件  user.js
export default {
  namespace: 'userinfo',
  state: {
    width: '-100%',
    hasUserInfoActive: false,
    info: undefined,
  },
  reducers: {
    // 打開我的資料
    open(state) {
      return {
        ...state,
        width: '0%',
        hasUserInfoActive: true,
      };
    },
     
  },
  effects: {
    * init(res, { put, select }) {
      const { userinfo } = yield select();
      if (userinfo.info === undefined) {
        try {
          const list = yield DATABASE.Friend().getSelfInfo();
          // console.log(list);

          yield put({ type: 'saveUserInfo', payload: list });
        } catch (e) {
          console.error(e);
        }
      }
    },
  },
};

// user.jsx,業務組件文件
import {connect} from 'dva'

class App extends Component {
     componentDidMount(){
    //省掉了mapActionsToPops這一步
    this.props.dispatch({
        type:"user/open"
    })
    } 

}

export default  connect(
    //至關於mapStateToState,能夠經過this.props.user拿到數據
(({user} )=>{
    user
} )
)(App)
狀態管理的最佳實踐,應該說推薦 dva,再次感謝前輩的開源。

UI組件庫,因爲本人平時都不使用UI庫了,因此可能會遺漏。

  • Ant-Design,pc版 ,製做後臺管理系統的神器,一樣要感謝前輩們的開源。前端

    • 關鍵字,webpack按需加載,配置默認樣式,

clipboard.png

使用 babel-plugin-import(推薦)。

// .babelrc or babel-loader option
{
  "plugins": [
    ["import", {
      "libraryName": "antd",
      "libraryDirectory": "es",
      "style": "css" // `style: true` 會加載 less 文件
    }]
  ]
}

而後只需從 antd 引入模塊便可,無需單獨引入樣式。等同於下面手動引入的方式。

// babel-plugin-import 會幫助你加載 JS 和 CSS
import { DatePicker } from 'antd';
  • Ant-Degsin-mobilejava

    • 關鍵字,按需加載,默認樣式修改
使用 babel-plugin-import(推薦)。
// .babelrc or babel-loader option
{
  "plugins": [
    ["import", { libraryName: "antd-mobile", style: "css" }]
     // `style: true` 會加載 less 文件
  ]
}
而後只需從 antd-mobile 引入模塊便可,無需單獨引入樣式。
// babel-plugin-import 會幫助你加載 JS 和 CSS
import { DatePicker } from 'antd-mobile';

Ant Design Mobile RN of React

clipboard.png

  • react-native中使用Ant-Designreact

    • yarn add @ant-design/react-native
    • babel配置中:linux

      "plugins": [
      ["import", { libraryName: "@ant-design/react-native" }]
      ]
  • React-native組件中使用:
import React from 'react';
import { View, Text, FlatList, SectionList, Alert } from 'react-native';
import { Button, Flex } from '@ant-design/react-native';
export default class Apps extends React.Component {
  render() {
    return (
      <View>
        <Button
          onPress={() => {
            Alert.alert(12312312);
          }}
        >
          12345561
        </Button>
      </View>
    );
  }
}

ElectronPC端跨平臺技術方案,集成Node,能夠開發極爲複雜的應用

clipboard.png

  • 渲染進程和主進程採用remote模塊或者ipc通訊方式進行通訊,進而能夠呼叫原生接口
  • 完美解決mac os , windows,linux上的三端統一開發沒有兼容性問題的框架
  • Electron 結合了 Chromium、Node.js 和用於調用操做系統本地功能的 API(如打開文件窗口、通知、圖標等)
  • 基於 Electron的開發就像在開發網頁,並且可以無縫地 使用 Node。或者說:在構建一個 Node 應用的同時,經過 HTML 和 CSS 構建界面。另外,你只需爲一個瀏覽器(最新的 Chrome)進行設計(即無需考慮兼容性等)

clipboard.png

import React from 'react';
import { HashRouter, Route, Switch } from 'dva/router';
import { ipcRenderer, remote } from 'electron';
ipcRenderer.removeAllListeners();
  ipcRenderer.on('loginSuccess', () => {
    ipcRenderer.send('reply', 'loginSuccess');
    props.history.push('/login/loading');
    props.dispatch({ type: 'globalstate/saveStatus', payload: 1 });
  });
這是一個很是不錯,並且考驗一位前端工程師底層技術的框架,可能會寫到大量底層 Node.js和原生 javascript,目前開發 IM項目不少使用這個框架。 github上的 star量也快 80K了。

clipboard.png

react-native,移動端跨平臺框架

跨平臺開發首選 Mac,沒有爲何

clipboard.png

clipboard.png

  • 搭建完成後,執行react-native run-ios
  • command+d開啓熱更新

clipboard.png

  • react遷移到react-native成本並不高,難的是適配和踩坑,遇到問題要多百度,rn的生態也很強大,並且給咱們封裝了不少內容,也可使用一些原生的接口.

clipboard.png

React-native的層次架構:
  • Java層:該層主要提供了Android的UI渲染器UIManager(將JavaScript映射成Android Widget)以及一些其餘的功能組件(例如:Fresco、Okhttp)等,在java層均封裝爲Module,java層核心jar包是react-native.jar,封裝了衆多上層的interface,如Module,Registry,bridge等。
  • C++層:主要處理Java與JavaScript的通訊以及執行JavaScript代碼工做,該層封裝了JavaScriptCore,執行對js的解析。基於JavaScriptCore,Web開發者能夠盡情使用ES6的新特性,如class、箭頭操做符等,並且 React Native運行在JavaScriptCore中的,徹底不存在瀏覽器兼容的狀況。Bridge橋接了java , js 通訊的核心接口。JSLoader主要是未來自assets目錄的或本地file加載javascriptCore,再經過JSCExectutor解析js文件。
  • Js層:該層提供了各類供開發者使用的組件以及一些工具庫。
  • Component:Js層通js/jsx編寫的Virtual Dom來構建Component或Module,Virtual DOM是DOM在內存中的一種輕量級表達方式,能夠經過不一樣的渲染引擎生成不一樣平臺下的UI。component的使用在 React 裏極爲重要, 由於component的存在讓計算 DOM diff 更高效。
  • ReactReconciler : 用於管理頂層組件或子組件的掛載、卸載、重繪。
注:JSCore,即JavaScriptCore,JS解析的核心部分,IOS使用的是內置的JavaScriptCore,Androis上使用的是 https://webkit.org 家的jsc.so。

啓動過程的解析:webpack

  • 1.ReactInstanceManager建立時會配置應用所需的java模塊與js模塊,經過ReactRootViewstartReactApplication啓動APP
  • 2.在建立ReactInstanceManager同時會建立用於加載JsBundle的JSBundlerLoader,並傳遞給CatalystInstance
  • 3.CatalystInstance會建立Java模塊註冊表及Javascript模塊註冊表,並遍歷實例化模塊。
  • 4.CatalystInstance經過JSBundlerLoader向Node Server請求Js
  • Bundle,並傳遞給JSCJavaScriptExectutor,最後傳遞給javascriptCore,再經過ReactBridge通知ReactRootView完成渲染。
Js與Java通訊機制
  • Java與Js之間的調用,是以兩邊存在兩邊存在同一份模塊配置表,最終均是將調用轉化爲{moduleID,methodID,callbackID,args},處理端在模塊配置表裏查找註冊的模塊與方法並調用。
Java 調用 Js
  • Java經過註冊表調用到CatalystInstance實例,透過ReactBridge的jni,調用到Onload.cpp中的callFunction,最後經過javascriptCore,調用BatchedBridge.js,根據參數{moduleID,methodID}require相應Js模塊執行。流程以下圖:

clipboard.png

  1. Js 調用Java
  • 若是消息隊列中有等待Java 處理的邏輯,並且 Java 超過 5ms 都沒有來取走,那麼 JavaScript 就會主動調用 Java 的方法,在須要調用調Java模塊方法時,會把參數{moduleID,methodID}等數據存在MessageQueue中,等待Java的事件觸發,把MessageQueue中的{moduleID,methodID}返回給Java,再根據模塊註冊表找到相應模塊處理。流程以下圖:

clipboard.png

參考文章,react-native原理解析,看在 react-native跨平臺開發的無縫對接 js和react份上,我決定堅決使用它。但願在1.0版本到來的時候,給咱們一個驚喜。

京東的Taro,多端解決方案

clipboard.png

  • Taro 是一套遵循 React 語法規範的 多端開發 解決方案。現現在市面上端的形態多種多樣,Web、React-Native、微信小程序等各類端大行其道,當業務要求同時在不一樣的端都要求有所表現的時候,針對不一樣的端去編寫多套代碼的成本顯然很是高,這時候只編寫一套代碼就可以適配到多端的能力就顯得極爲須要。
  • 使用 Taro,咱們能夠只書寫一套代碼,再經過 Taro 的編譯工具,將源代碼分別編譯出能夠在不一樣端(微信/百度/支付寶/字節跳動小程序、H五、React-Native 等)運行的代碼。

clipboard.png

  • 代碼示例:
import Taro, { Component } from '@tarojs/taro'
import { View, Button } from '@tarojs/components'

export default class Index extends Component {
  constructor () {
    super(...arguments)
    this.state = {
      title: '首頁',
      list: [1, 2, 3]
    }
  }

  componentWillMount () {}

  componentDidMount () {}

  componentWillUpdate (nextProps, nextState) {}

  componentDidUpdate (prevProps, prevState) {}

  shouldComponentUpdate (nextProps, nextState) {
    return true
  }

  add = (e) => {
    // dosth
  }

  render () {
    return (
      <View className='index'>
        <View className='title'>{this.state.title}</View>
        <View className='content'>
          {this.state.list.map(item => {
            return (
              <View className='item'>{item}</View>
            )
          })}
          <Button className='add' onClick={this.add}>添加</Button>
        </View>
      </View>
    )
  }
}
  • 關鍵字,編譯成不一樣的平臺應用輸出
  • Taro擁有本身的腳手架 腳手架配置
爲何會加入 Taro,由於它是國產,基於 react,應該支持。並且相信將來它應該有不錯的前景。
  • 環境搭建:ios

    • 首先,你須要使用 npm 或者 yarn 全局安裝@tarojs/cli,或者直接使用npx:
    • $ yarn global add @tarojs/cli
    • 使用命令建立模板項目 $ taro init myApp

clipboard.png

  • 選擇微信小程序模式,須要自行下載並打開微信開發者工具,而後選擇項目根目錄進行預覽。
  • 微信小程序編譯預覽及打包(去掉 --watch 將不會監聽文件修改,並會對代碼進行壓縮打包)
# yarn
    $ yarn dev:weapp
    $ yarn build:weapp
    # npm script
    $ npm run dev:weapp
    $ npm run build:weapp
    # 僅限全局安裝
    $ taro build --type weapp --watch
    $ taro build --type weapp
    # npx 用戶也可使用
    $ npx taro build --type weapp --watch
    $ npx taro build --type weapp
  • H5 模式,無需特定的開發者工具,在執行完下述命令以後便可經過瀏覽器進行預覽
# yarn
    $ yarn dev:h5
    # npm script
    $ npm run dev:h5
    # 僅限全局安裝
    $ taro build --type h5 --watch
    # npx 用戶也可使用
    $ npx taro build --type h5 --watch
  • React Native
# yarn
    $ yarn dev:rn
    # npm script
    $ npm run dev:rn
    # 僅限全局安裝
    $ taro build --type rn --watch
    # npx 用戶也可使用
    $ npx taro build --type rn --watch
Taro也擁有本身的生態圈,很是龐大,很是感謝京東的開源,但願它的功能愈來愈強大。

最終總結:

  • React自己很強大,生態圈很是強大,能夠說任何平臺的大型應用均可以讓它來作,加上hook的出現,將來可期。
  • 用什麼框架,什麼技術繪製UI並不重要,可是本人以爲jsreact的無縫對接下更偏向rn,taroelectron這類型的框架開發跨平臺應用。
  • 後期會再出關於react的優化彙總,以爲寫得不錯的能夠點個贊~謝謝
相關文章
相關標籤/搜索