Paul Fabbroni
Paul Fabbroni

Reputation: 123

Redux Selectors in Mithril

I've been tasked with implementing selectors in our redux application. Everything I'm reading online about redux selectors talks about React and how you can replace what is in mapStateToProps with a selector. What is the equivalent/where would i do this in a mithril app?

Upvotes: 0

Views: 501

Answers (2)

ArneHugo
ArneHugo

Reputation: 6509

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

Firstly, you don't need an equivalent, you can just use the exact same selectors that you would in a React application.

Where to call selectors?

You can call the selectors wherever you want, but I recommend calling them as close to where the data is used as possible. Don't call selectors in a component high up in the component hierarchy only to pass the data down via several components before they end up in a component that actually uses the data – unless you have a good reason to do so.

For most cases you can call the selectors inside a view-function, although you might come across cases where you need to call selectors in other lifecycle methods as well. In some applications you might also want to use selectors in m.render as well.

A couple of examples off the top of my head:

  1. Inside the view function when creating DOM-elements

    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. Inside the view function when creating Mithril components

    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. Inside m.render

    In this example, we have a game that requires us to re-render the whole page after any change.

    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;
        }
    });
    

Upvotes: 1

chautelly
chautelly

Reputation: 467

I'm not familiar with Mithril, but Redux state selectors are independent from React. They are just functions that expect state and return a:

  • a slice of state
  • or data derived from state

For example, if I my Redux state has an entry named records containg a list of models:

{
    records: [ ... ],
}

I could create a selector returning the length:

const numOfRecords = state => state.records.length

Or if my state also keeps track of a sortBy value:

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

Selectors can be helpful to increase performance and reduce the need for updates. (reselect is a great module for this).

They are also great for developing modular pieces of code that depend on data stored in application state but don't really want to know where that data comes from.

Upvotes: 1

Related Questions