Redux:除了在发送动作时减少或渲染以外的其他操作

时间:2016-01-28 20:17:32

标签: redux

我试图理解redux背后的概念。

考虑这个非常简单的用户界面:

 +-------+-------+-------+
 | Tab A | Tab B | Tab C |
 |       +--------------------+
 | one ................ $1.22 |          
 | two ................ $3.22 |
 | three ............ $211.99 |

状态有一个对象itemsById和一个数组currentlyVisibleItemIds,很容易呈现。

我还打开了一个websocket,可以提供不变的价格更新并使用store.dispatch()转发它们。 reducer创建一个新的更新itemsById对象并重新呈现价格。一切都好。

但是,出于效率原因,我只想听取当前可见项目的价格更新,因此每当currentlyVisibleItemIds更改时我都必须通过套接字发送订阅命令。

对于我的生活,我找不到一个放这个逻辑的好地方。如果我在websocket代码中store.subscribe()进行了所有更改,则必须手动确定currentlyVisibleItemIds是否已更改。从减速器调用websocket感觉非常错误。它应该进入thunk,以便从动作中调用websocket代码吗?

任何建议表示赞赏。

更新

这是我现在拥有的。看起来有点笨重,因为我必须手动确定currentlyVisibleItemIds是否已更改:

function PriceFeed(port, store) {

    var webSocket, isConnected, previousItems, unsubscribeFunc;

    function onOpen() {
        isConnected = true;
    }

    function onMessage(event) {
        var json = JSON.parse(event.data);
        if (json.type === 'updates') {
            store.dispatch({
                type: 'PRICE_UPDATES',
                data: json.prices
            });
        }
    }

    function storeChangeHandler() {
        if (!isConnected) {
            return;
        }
        var currentItems = store.getState().currentlyVisibleItemIds;
        if (currentItems != previousItems) {
            webSocket.send(JSON.stringify({
                type: 'subscription',
                ids: currentItems
             }));
            previousItems = currentItems;
        }
    }

    webSocket = new WebSocket(`ws://${location.hostname}:${port}`);
    webSocket.addEventListener('message', onMessage);
    webSocket.addEventListener('open', onOpen);
    unsubscribeFunc = store.subscribe(storeChangeHandler);
}

1 个答案:

答案 0 :(得分:0)

假设您正在跟踪商店中的可见商品,

redux-thunk应该可以很好地处理这个问题。在收到消息的WS回调中,您可以这样做:

store.dispatch(PriceUpdate(itemID, price))

其中PriceUpdate定义为

function PriceUpdate(itemID, price) {
  return (dispatch, getState) => {
    if (getState().visibleItems.includes(itemID)) {
      dispatch({ type: PRICE_UPDATE, payload: { itemID, price });
    }
  }
}

那就是说,我会对这里的过早优化保持警惕。在大多数情况下,即使是非常大量的交易,也可能值得保持所有本地数据的新鲜度,无论其是否在视野中。但是,当然,我不知道这里的背景,并且肯定存在这样的情况。