如何在已有的 Web 應用中使用 ReactJS

原文:How to Sprinkle ReactJS into an Existing Web Applicationreact

譯者:nzbinweb

當咱們學習一項新技術,多是一個 JavaScript 框架,也多是一個 CSS 方法,咱們將面對這樣的挑戰 如何在舊網站上運用這項新技術?。不少教程講述瞭如何從頭開始,但卻很難運用到實際工做中。app

在這篇教程中,我會經過一些很基本的例子講解如何靈活運用 ReactJS,以及替換使用 jQuery 寫的代碼。框架

從 jQuery 到 React

我最近的任務是用 React 重構一個使用 jQuery 寫的功能。這個過程困難重重,由於大量的 jQuery 分散在代碼段中。使用 jQuery 構建全部的 UI 是可能的(咱們已經這樣作了不少年),可是在規模變大以後,將變得混亂且難以維護。dom

不管你使用 Angular, Ember, Vue, React, 或者只是 jQuery,你所作的事情和開發者多年來所作的事情是同樣的:函數

渲染 HTML > 接收用戶事件 > 從新渲染 HTML工具

由於 jQuery 很是依賴選擇器好比  .classes#IDs 去控制 DOM,因此大量的屬性會使 HTML 變得容易混淆,而這些屬性的目的只是方便 jQuery 查找。若是代碼量比較小,這是沒有問題的, 可是若是代碼量龐大,就會很難知道哪些類用於 CSS,哪些類用於 JavaScript。若是你以前爲了改變一個功能而在 HTML 模板或 JavaScript 中查找 find 一個 .class 或者 #ID 選擇器,你應該明白我說的。佈局

過渡依賴 .classes#IDs 的選擇來操縱 HTML 並不輕鬆。學習

因此,若是你的代碼是用 jQuery 或者其它框架所寫,那麼應該如何使用 React 去替換這些 UI 片斷?網站

開始以前應該瞭解的事情

Wrapper / Container 元素

不管使用 jQuery 仍是下一個流行框架開發應用,大多數狀況都是用一個根元素包裹 UI 片斷。若是代碼庫使用 jQuery,一般會有一個元素充當 wrapper 選擇器。使用 jQuery 選擇 wrapper 元素,它被用於動態更新 DOM。

<!-- 
  .MyAwesomeFeature acts as a container to select 
  and manipulate child components with jQuery.
-->
<div class="MyAwesomeFeature">
  <div class="MyAwesomeFeature__title"></div>
  <div class="MyAwesomeFeature__image"></div>
</div>

<script>
  var container = $(".MyAwesomeFeature");
  $(".MyAwesomeFeature__title", container).text("Hello World!");

  // Other DOM changes, event handlers, etc...
</script>

獨立狀態 vs. 共享狀態

能夠看一下你的應用中的功能狀態是獨立 isolated 於 container 元素仍是在多個元素中共享 shared

相關教程: Getting Started with React

  1. 獨立狀態 -  這種狀態獨立存在於 container 元素中。全部按鈕、輸入框等的交互狀態都由這個 wrapper / container 元素分享。

  2. 共享狀態 - 這種狀態由多個元素共享。好比,從頁面其它位置的日期下拉框中更新日曆。 菜單和日曆在不一樣的容器中,可是它們的狀態是共享的。

我將用 jQuery 和 ReactJS 作的 4 個例子解釋共享/獨立狀態的概念。

用 jQuery 實現獨立狀態

假設咱們有一個 web 應用,它展現了一個 emoji,當點擊按鈕,會隨機展現一個新的 emoji。下面的代碼是一個典型的 jQuery 應用,咱們選擇父級元素 .mood-container ,而後動態改變內容。

如下是例子 的 HTML:

<!--
    Demonstrates how jQuery can be used to 
    use a container as a selector and update 
    the content within.
-->
<div id="mood-container">
  <div class="Mood">
    <div class="Mood__emoji"></div>
    <div class="Mood__name">[ Emoji Placeholder ]</div>
    <button class="Mood__button">Random Mood</button>
  </div>
</div>

See the Pen Isolated state with jQuery by Andrew Del Prete (@andrewdelprete) on CodePen.

這並非使用 jQuery 更改 DOM 的惟一策略,但很常見。

用 ReactJS 實現獨立狀態

使用如 React 的庫的好處之一就是能夠將上面的 JavaScript 和 HTML 封裝成一個組件 component 。它是一個更可靠、可維護、可重用的功能部件。

這在處理大型應用時很是有用,由於組件 component 的渲染和更新是同步的。我並非指將關注點與邏輯和視圖層混合在一塊兒,而是如何將 JavaScript 和 HTML 以組件 component 的形式組織代碼。這是全部 JavaScript 框架的共同理念,所以被稱爲 Framework

全部框架一般都是:

  1. 掛載到特殊的容器 container上 ( 好比 App 中名爲 #ID 的 div )。
  2. 向容器 container 中渲染內容。
  3. 負責跟蹤和更新容器 container 中的內容。
  4. 負責移除容器 container 中的內容。

如下是使用 React 整合後的新的 HTML:

<!--
    Demonstrates how ReactJS mounts itself 
    to a container and takes it from there.
-->
<div id="mood-container" />

See the Pen Isolated state with ReactJS by Andrew Del Prete (@andrewdelprete) on CodePen.

用 jQuery 實現共享狀態

使用 jQuery 能夠很容易實現,可是,若是一個區域動態影響另外一個單獨使用選擇器的區域時,可能會變得混亂。另外,當你使用 .classes 以及 #IDs 做爲選擇器手動控制 DOM 的時候,你要負責跟蹤全部事情的開銷。

See the Pen Shared state with jQuery by Andrew Del Prete (@andrewdelprete) on CodePen.

在這個例子中,咱們經過 .Mood__name.Mood__button-name 選擇器分享 mood name ,而且經過一個容器中的按鈕去更新另外一個容器中的 emoji 。這還能夠寫的更簡單一些,可是無論怎樣,當嘗試用 jQuery 選擇器單獨管理全部這些事情時,就會變得很糟糕。

用 ReactJS 實現共享狀態

在 ReactJS 中,一般有兩個分享組件狀態的方法:

  1. 將組件包裹在 container 元素中去管理狀態,將數據/函數做爲 props 向組件傳遞。
  2. 使用相似 Redux 的工具在全局定義狀態和 actions,而後將組件掛載上去。

使用 Container 分享狀態

這是使用  React 渲染比較常見的方式,尤爲 SPA 應用或者 UI 片斷。由於咱們但願組件之間通訊,因此咱們將它們放置在父級組件中,而後向下傳遞屬性來更新每一個子組件。這是 ReactJS 最基本的工做方式。

這種方式適用於多個 UI 組件被一個父組件包裹的狀況。不少以前建立的應用可能不適合,可是能夠根據 UI 佈局狀況選擇使用。

See the Pen Shared state with ReactJS - Container by Andrew Del Prete (@andrewdelprete) on CodePen.

使用 Redux 分享狀態

相似 Redux(flux 的另外一種實現)的庫能夠很容易的實現應用中不一樣組件之間的通訊。能夠將 actions 和狀態屬性掛載到組件,經過更新全局對象 Redux 來分享狀態。

See the Pen Shared state with ReactJS - Redux by Andrew Del Prete (@andrewdelprete) on CodePen.

總結

我但願這篇文章可讓你更好地瞭解須要關注的內容以及如何將 ReactJS 運用到現有的應用中。主要的解決方法就是,若是你使用 jQuery 處理 UI 片斷,那麼你能夠將容器元素替換成一個 React 組件。若是你須要在多個組件中分享狀態,那麼你可使用容器方法或者相似 Redux 的庫。

感謝閱讀!

-Andrew Del Prete

相關文章
相關標籤/搜索