在使用 React + Flux 几个月后,我遇到了同样的问题并尝试了一些不同的方法。
我得出的结论是,最好的方法是让操作处理远程和本地的数据更新:
# COMPONENT
TodoItems = React.createClass
componentDidMount: ->
TodoStore.addListener("CHANGE", @_onChange)
_onChange: ->
@setState {
todos: TodoStore.get()
_onKeyDown: (event) ->
if event.keyCode == ENTER_KEY_CODE
content = event.target.value.trim()
TodoActions.add(content)
render: ->
React.DOM.textarea {onKeyDown: @_onKeyDown}
# ACTIONS
class TodoActions
@add: (content) ->
Dispatcher.handleAction({type: "OPTIMISTIC_TODO_ADD", todo: {content: content}})
APICall.addTodo({content: content})
# STORE
class TodoStore extends EventEmitter
constructor: ->
@todos = [] # this is a nice way of retrieving from localStore
@dispatchToken = @registerToDispatcher()
get: ->
return @todos
registerToDispatcher: ->
Dispatcher.register (payload) =>
type = payload.type
todo = payload.todo
response = payload.response
switch type
when "OPTIMISTIC_TODO_ADD"
@todos.push(todo)
@emit("CHANGE")
when "TODO_ADD"
# act according to server response
@emit("CHANGE") # or whatever you like
#### APICall
class APICall # what can be called an 'action creator'
@addTodo: (todo) ->
response = http.post(todo) # I guess you get the idea
Dispatcher.handleAction({type: "TODO_ADD", response: response})
如您所见,“果汁”在TodoActions 内。添加待办事项后,TodoActions.add() 可以通过 OPTIMISTIC_TODO_ADD 触发乐观 UI 更新,该更新将插入到 TodoStore.todos 中。同时,它知道这必须传达给服务器。
一个外部实体——ApiCall(可以被认为是一个动作创建者)——负责处理这个动作的远程部分,当你得到一个响应时,它会按照正常的过程对TodoStore进行相应的操作。
如果您让商店直接负责远程内容管理,您将为其增加一层额外的复杂性,这让我对某个时刻的数据状态失去信心。
让我们想象一下:
class TodoActions
# TodoActions is `dumb`, only passes data and action types to Dispatcher
@add: (content) ->
Dispatcher.handleAction({type: "TODO_ADD", todo: {content: content}})
# APICall.addTodo({content: content})
class TodoStore extends EventEmitter
# ...
registerToDispatcher: ->
# ...
when "TODO_ADD"
@todos.push(todo)
# now the store has to push it to the server
# which means that it will have to call actions or the API directly = BAD
# lest assume:
APICall.addTodo({content: content})
# it also generates some uncertainty about the nature of the event emit:
# this change can guarantee that data was persisted within the server.
@emit("CHANGE")
根据我的经验,我首先介绍的解决方案提供了一种对 UI 进行乐观更新、处理错误和显示加载指示的好方法。