question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@dai-shi @theKashey @ScriptedAlchemy

So I’ve been doing some thinking around selectors, and I’ve come to the conclusion that the babel plugin approach is a horrible path to hell. I’ll describe why in a second. Here’s the alternative:

function MyComponent(props) {
   const state = useReduxState(props, someArgEtc) // here's the important line
   return <div>{state.fooSelector(props, someArgEtc)}</div>
}

===

function MyComponent(props) {
   const state = useReduxState()
   return useMemo(<div>{state.fooSelector(props, someArgEtc)}</div>, [props, someArgEtc])
}

So, basically we make the user/developer do a little bit of work by providing the dependencies to track. And we dont make em think about useMemo.


Of course to do this properly, rests on useReduxState knowing about selectors, so therefore Redux must be forked to have this createStore API:

const selectors = {
   fooSelector: (state, props, someArgEtc) => ...,
   anotherSelector: (state, etc) => ...
}
const store = createStore(reducers, selectors) // both are automatically "combined"

Now, we know what selectors we have like reducers. Therefore, the proxy can prevent re-render from within the hook. It does so by shallow comparison of the argument dependencies.

Hell, we could even accomplish this without a fork of redux. useReduxState can accept additional args that are simply compared for changes. And of course it’s up to the developer to match with actual usage of selectors.


Why we dont wanna mess with babel?

Here’s why:

function RespondComponent(props, state, actions) {
    if (props.foo) return <div>{state.selectorA(props)}</div>
    return <div>{state.selectorB(props)}</div>
}

–>

function RespondComponent(props, state, actions) {
    if (props.foo) {
        const valA = state.selectorA(props)
        return useMemo(<div>{valA}</div>, [valA])
    }

     const valB = state.selectorB(props)
     return useMemo(<div>{valB}</div>, [valB])
}

And that’s the easiest possible example!

If making all the appropriate visitations of selectors in search of selectors is even 100% reliable, then taking this to the next level where selectors are correctly conditionally depended upon is even more error-prone.

Also, nobody talks about babel compilation speed, but this stuff adds up. Nobody wants compilation time decreased because of this stuff.

Anyway the reliability factor is just too low based on my experience doing babel plugins.


Now that all said, I think we’ve found the perfect solution for how to handle this in runtime code within existing proxies! The only caveat is you have to have a store creation mechanism like in Respond Framework. Which isn’t really a caveat since that’s the exact direction we’re going, and since we could also just give useReduxState additional super powers of bail-out capabilities through passing it deps, as if it was useMemo.

Any tips to make this a reality are much appreciated.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:13 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
ScriptedAlchemycommented, Mar 28, 2019

Late to the party here! For context, I work with @faceyspacey 😃

@dai-shi @theKashey you’ve done some fantastic work on this project. I’ve become a heavy promoter and dependent on this project, and I intend to roll react-hooks-easy-redux out to all major companies I work for. This is a substantial improvement in DX compared to react-redux!

Id love to work with you guys in whatever capacity you may have. OSS is a labor of love and I know time is always working against us all - but just this thread and the work to come from is has been really awesome - hard problems solved! It would be fun for us to work together especially as we all seem geared to tackling the exciting challenges that are a little harder to solve. We are all busy, but some effective collaboration could user in a profound new era of React development.

1reaction
faceyspaceycommented, Mar 25, 2019

useMemo can be used in userland.

But as I mentioned above, to handle all scenarios with babel, and automatically do this for the user is not reliable. at the very least, it’s extremely challenging to achieve 100% reliability.

dai-shi, i’m gonna be releasing docs for Respond Framework soon. I’m putting together an informal team of allstars. I want to extend you an invitation to join us. There will be 4-5 core team members. You won’t have to do anymore than you want to. It could be just a badge of honor if you want. Basically I want to give credit to the fundamental work you’ve done here, as we do a lot to promote a beautiful new API for the Redux ecosystem. And Anton, as you know, the invitation has been extended since basically last year. Zack and I already consider you part of our team.

Read more comments on GitHub >

github_iconTop Results From Across the Web

reduxjs/reselect: Selector library for Redux
Reselect. A library for creating memoized "selector" functions. Commonly used with Redux, but usable with any plain JS immutable data as well.
Read more >
Deriving Data with Selectors
Selectors are primarily used to encapsulate logic for looking up specific values from state, logic for actually deriving values, ...
Read more >
React re-reselect: Better memoization and cache ...
Selectors. Essentially, selectors are functions that take Redux state as an input and return a value derived from that state. In React Redux, ......
Read more >
Understanding Javascript Selectors With and Without ...
The short answer is: for performance as Reselect provides a wrapper for creating selectors that are memoized. The examples of selectors that you ......
Read more >
Performant Redux Selectors with Reselect
Selectors created using Reselect's createSelector function are memoized. That's a fancy word to mean that the function remembers the arguments ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found