簡體   English   中英

套接字在哪里適合Flux單向數據流?

[英]Where do sockets fit into the Flux unidirectional data flow?

套接字在哪里適合Flux單向數據流? 我已經閱讀了兩種思路,即遠程數據應該進入Flux單向數據流。 我看到獲取Flux應用程序的遠程數據的方式是在進行服務器端調用時,例如,在承諾中解析或拒絕。 在此過程中可能會觸發三種可能的操作:

  1. 樂觀更新視圖的初始操作(FooActions.BAR)
  2. 解決異步承諾時的成功操作(FooActions.BAR_SUCCESS)
  3. 異步承諾被拒絕時的錯誤操作(FooActions.BAR_ERROR)

商店將監聽操作並更新必要的數據。 我已經看到了來自動作創建者和商店內部的服務器端調用。 我使用動作創建器進行上述過程,但我不確定是否應該通過Web套接字獲取數據。 我想知道插座適合下圖。

在此輸入圖像描述

使用Flux與WebSockets或普通的舊HTTP請求/輪詢的方式確實沒有區別。 您的商店負責在應用程序狀態更改時發出更改事件,如果該更改來自UI交互,WebSocket或發出HTTP請求,則不應從商店外部看到它。 這實際上是Flux的主要優點之一,無論應用程序狀態在何處發生變化,它都會經歷相同的代碼路徑。

一些Flux實現傾向於使用動作/動作創建器來獲取數據,但我不同意這一點。

操作是發生修改應用程序狀態的事情。 這就是“用戶更改了一些文本並點擊保存”或“用戶刪除了一個項目”。 想想像數據庫的事務日志這樣的操作。 如果丟失了數據庫,但保存並序列化了所有發生的操作,則可以重放所有這些操作,最終得到丟失的相同狀態/數據庫。

所以像“給我帶有身份X的項目”和“給我所有項目”這樣的事情不是行動,而是問題,關於該申請狀態的問題。 在我看來,這些商店應該通過您在這些商店中公開的方法來回應這些問題。

使用動作/動作創建器進行提取很誘人,因為提取需要異步。 通過將異步內容包裝在操作中,您的組件和存儲可以完全同步。 但是,如果你這樣做,你會模糊一個動作的定義,它也會強迫你假設你可以將整個應用程序狀態放在內存中(因為你只能在內存中得到答案時才能同步響應)。

所以這就是我如何看待Flux和不同的概念。

商店

這顯然是您的應用程序狀態所在的位置。 商店封裝和管理狀態,是該狀態實際發生突變的唯一地方。 它也是當狀態發生變化時發出事件的地方。

商店還負責與后端通信。 當狀態發生變化並且需要與服務器同步時,商店與后端通信,並且當它需要內存中沒有的數據時,它還與服務器通信。 它有get(id)search(parameters)等方法。這些方法都是針對你的問題,它們都返回了promises,即使狀態可以適應內存。 這很重要,因為您最終可能會遇到狀態不再適合內存的情況,或者無法在內存中進行過濾或進行高級搜索的情況。 通過從您的問題方法返回promise,您可以在從內存返回或詢問后端之間切換,而無需更改商店外的任何內容。

操作

我的行為非常輕量級,並且他們對持久化它們所包含的突變一無所知。 他們只是意圖從組件變異到商店。 對於較大的應用程序,它們可以包含一些邏輯,但絕不會包含服務器通信。

組件

這些是您的React組件。 它們通過調用商店中的問題方法並呈現這些方法的返回值來與商店進行交互。 他們還訂閱了商店公開的change事件。 我喜歡使用更高階的組件 ,這些組件只是包裝另一個組件並將props傳遞給它。 一個例子是:

var TodoItemsComponent = React.createClass({
  getInitialState: function () {
    return {
      todoItems: null
    }
  },
  componentDidMount: function () {
    var self = this;
    TodoStore.getAll().then(function (todoItems) {
      self.setState({todoItems: todoItems});
    });

    TodoStore.onChange(function (todoItems) {
      self.setState({todoItems: todoItems});
    });
  },
  render: function () {
    if (this.state.todoItems) {
      return <TodoListComponent todoItems={this.state.todoItems} />;
    } else {
      return <Spinner />;
    }
  }
});

var TodoListComponent = React.createClass({
  createNewTodo: function () {
    TodoActions.createNew({
      text: 'A new todo!'
    });
  },
  render: function () {
    return (
      <ul>
        {this.props.todoItems.map(function (todo) {
          return <li>{todo.text}</li>;
        })}
      </ul>
      <button onClick={this.createNewTodo}>Create new todo</button>
    );
  }
});

在這個例子中, TodoItemsComponent是更高階的組件,它包含了與商店通信的細節。 它在獲取TodoListComponent時呈現TodoListComponent ,並在此之前呈現一個微調器。 因為它將todo項目作為道具傳遞給TodoListComponent ,組件只需要專注於渲染,並且只要存儲中的任何更改,它就會被重新渲染。 並且渲染組件保持完全同步。 另一個好處是TodoItemsComponent只專注於獲取數據並將其傳遞,使其對任何需要todos的渲染組件都非常可重用。

更高階的組件

術語高階分量來自術語高階函數。 高階函數是返回其他函數的函數。 因此,更高階的組件是一個只包裝另一個組件並返回其輸出的組件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM