Mithril 中的 Redux 选择器

Redux Selectors in Mithril

我的任务是在我们的 redux 应用程序中实现选择器。我在网上阅读的所有关于 redux 选择器的内容都在谈论 React 以及如何用选择器替换 mapStateToProps 中的内容。 equivalent/where 我会在秘银应用程序中执行此操作吗?

我不熟悉 Mithril,但 Redux 状态选择器独立于 React。它们只是期望状态和 return a:

的函数
  • 一片状态
  • 或来自状态的数据

例如,如果我的 Redux 状态有一个名为 records 的条目,其中包含一个模型列表:

{
    records: [ ... ],
}

我可以创建一个选择器 return 长度:

const numOfRecords = state => state.records.length

或者如果我的状态也跟踪 sortBy 值:

const sortedRecords = state => state.records.sort(sortByFn(state.sortBy))

选择器有助于提高性能并减少更新需求。 (reselect 是一个很棒的模块)。

它们也非常适合开发依赖于存储在应用程序状态中的数据但又不想知道这些数据来自何处的模块化代码。

What is the equivalent/where would i do this in a mithril app?

首先,您不需要等效的选择器,您只需使用与在 React 应用程序中完全相同的选择器即可。

在哪里调用选择器?

您可以在任何地方调用选择器,但我建议在尽可能靠近使用数据的地方调用它们。不要在组件层次结构中较高的组件中调用选择器,只是为了在数据最终进入实际使用数据的组件之前通过多个组件向下传递数据——除非你有充分的理由这样做。

在大多数情况下,您可以在 view 函数中调用选择器,尽管您可能会遇到需要在其他 lifecycle methods as well. In some applications you might also want to use selectors in m.render 中调用选择器的情况。

举几个例子:

  1. 在创建 DOM-elements

    时在 view 函数中
    var LoggedinUserDetails = {
        view: function () {
            return m('', [
                m('', getLoggedinUserName(store.getState())), // getLoggedinUserName is a selector
                m('img', { src: getLoggedinUserImageUrl(store.getState()) }) // getLoggedinUserImageUrl is a selector
            ])
        }
    }
    
  2. 在创建秘银组件时的view函数内部

    var UserDetails = {
        view: function (attrs) {
            return m('', [
                m('', attrs.user.name),
                m('img', { src: attrs.user.imageUrl })
            ])
        }
    }
    
        ...
        m(UserDetails, { user: getLoggedInUserDetails(store.getState()) }) // getLoggedInUserDetails is a selector
    
  3. 里面m.render

    在此示例中,我们有一个游戏要求我们在任何更改后重新呈现整个页面。

    function onStateChange() {
        var state = store.getState();
    
        m.render(document.body, m(Game, {
            map: getMap(state),
            players: getPlayers(state),
            visibleArea: getVisibleArea(state)
        }));
    }
    
    // Receiving partial state updates from server via websockets
    websocket.on('update-map', function (map) {
        store.dispatch({ type: 'update-map', payload: map });
    });
    
    websocket.on('update-players', function (players) {
        store.dispatch({ type: 'update-players', payload: players });
    });
    
    // Changing state based on user input
    window.addEventListener('keydown', function (event) {
        switch (event.key) {
            case 'Enter':
                store.dispatch({ type: 'move-visible-area-to-next-player' });
                break;
        }
    });