動態(tài)交互式用戶界面

2019-08-14 14:28 更新

我們已經(jīng)學習如何使用 React 顯示數(shù)據(jù)?,F(xiàn)在讓我們來學習如何創(chuàng)建交互式界面。

簡單例子

var LikeButton = React.createClass({
  getInitialState: function() {    return {liked: false};
  },
  handleClick: function(event) {    this.setState({liked: !this.state.liked});
  },
  render: function() {    var text = this.state.liked ? 'like' : 'haven\'t liked';    return (      <p onClick={this.handleClick}>
        You {text} this. Click to toggle.      </p>
    );
  }
});

React.render(  <LikeButton />,
  document.getElementById('example')
);

事件處理與合成事件(Synthetic Events)

React 里只需把事件處理器(event handler)以駱峰命名(camelCased)形式當作組件的 props 傳入即可,就像使用普通 HTML 那樣。React 內(nèi)部創(chuàng)建一套合成事件系統(tǒng)來使所有事件在 IE8 和以上瀏覽器表現(xiàn)一致。也就是說,React 知道如何冒泡和捕獲事件,而且你的事件處理器接收到的 events 參數(shù)與 W3C 規(guī)范 一致,無論你使用哪種瀏覽器。

幕后原理:自動綁定(Autobinding)和事件代理(Event Delegation)

在幕后,React 做了一些操作來讓代碼高效運行且易于理解。

Autobinding: 在 JavaScript 里創(chuàng)建回調(diào)的時候,為了保證 this 的正確性,一般都需要顯式地綁定方法到它的實例上。有了 React,所有方法被自動綁定到了它的組件實例上。React 還緩存這些綁定方法,所以 CPU 和內(nèi)存都是非常高效。而且還能減少打字!

事件代理 : React 實際并沒有把事件處理器綁定到節(jié)點本身。當 React 啟動的時候,它在最外層使用唯一一個事件監(jiān)聽器處理所有事件。當組件被加載和卸載時,只是在內(nèi)部映射里添加或刪除事件處理器。當事件觸發(fā),React 根據(jù)映射來決定如何分發(fā)。當映射里處理器時,會當作空操作處理。參考David Walsh 很棒的文章 了解這樣做高效的原因。

組件其實是狀態(tài)機(State Machines)

React 把用戶界面當作簡單狀態(tài)機。把用戶界面想像成擁有不同狀態(tài)然后渲染這些狀態(tài),可以輕松讓用戶界面和數(shù)據(jù)保持一致。

React 里,只需更新組件的 state,然后根據(jù)新的 state 重新渲染用戶界面(不要操作 DOM)。React 來決定如何最高效地更新 DOM。

State 工作原理

常用的通知 React 數(shù)據(jù)變化的方法是調(diào)用 setState(data, callback)。這個方法會合并(merge) data  this.state,并重新渲染組件。渲染完成后,調(diào)用可選的 callback 回調(diào)。大部分情況下不需要提供 callback,因為 React 會負責把界面更新到最新狀態(tài)。

哪些組件應該有 State?

大部分組件的工作應該是從 props 里取數(shù)據(jù)并渲染出來。但是,有時需要對用戶輸入、服務器請求或者時間變化等作出響應,這時才需要使用 State。

嘗試把盡可能多的組件無狀態(tài)化。 這樣做能隔離 state,把它放到最合理的地方,也能減少冗余并,同時易于解釋程序運作過程。

常用的模式是創(chuàng)建多個只負責渲染數(shù)據(jù)的無狀態(tài)(stateless)組件,在它們的上層創(chuàng)建一個有狀態(tài)(stateful)組件并把它的狀態(tài)通過 props 傳給子級。這個有狀態(tài)的組件封裝了所有用戶的交互邏輯,而這些無狀態(tài)組件則負責聲明式地渲染數(shù)據(jù)。

哪些 應該 作為 State?

State 應該包括那些可能被組件的事件處理器改變并觸發(fā)用戶界面更新的數(shù)據(jù)。 真實的應用中這種數(shù)據(jù)一般都很小且能被 JSON 序列化。當創(chuàng)建一個狀態(tài)化的組件時,想象一下表示它的狀態(tài)最少需要哪些數(shù)據(jù),并只把這些數(shù)據(jù)存入 this.state。在 render() 里再根據(jù) state 來計算你需要的其它數(shù)據(jù)。你會發(fā)現(xiàn)以這種方式思考和開發(fā)程序最終往往是正確的,因為如果在 state 里添加冗余數(shù)據(jù)或計算所得數(shù)據(jù),需要你經(jīng)常手動保持數(shù)據(jù)同步,不能讓 React 來幫你處理。

哪些 不應該 作為 State?

this.state 應該僅包括能表示用戶界面狀態(tài)所需的最少數(shù)據(jù)。因些,它不應該包括:

  • 計算所得數(shù)據(jù): 不要擔心根據(jù) state 來預先計算數(shù)據(jù) —— 把所有的計算都放到 render() 里更容易保證用戶界面和數(shù)據(jù)的一致性。例如,在 state 里有一個數(shù)組(listItems),我們要把數(shù)組長度渲染成字符串, 直接在 render() 里使用 this.state.listItems.length + ' list items' 比把它放到 state 里好的多。

  • React 組件:  render() 里使用當前 props 和 state 來創(chuàng)建它。

  • 基于 props 的重復數(shù)據(jù): 盡可能使用 props 來作為惟一數(shù)據(jù)來源。把 props 保存到 state 的一個有效的場景是需要知道它以前值的時候,因為未來的 props 可能會變化。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號