Skip to content
This repository has been archived by the owner on May 23, 2018. It is now read-only.

Use of routeNodeSelector() with mapStateToProps() #14

Open
tomzmtl opened this issue Apr 24, 2017 · 7 comments
Open

Use of routeNodeSelector() with mapStateToProps() #14

tomzmtl opened this issue Apr 24, 2017 · 7 comments

Comments

@tomzmtl
Copy link

tomzmtl commented Apr 24, 2017

Hi, I'm implementing the router in a standard react-redux app.

So far connecting component to router states was easy following the examples, for instance:

export default connect(routeNodeSelector('about'))(About);

but now I'd like to, in addition and the same component, retrieve a slice of the redux state using a classic mapStateToProps() function:

const mapStateToProps = state => ({
  progress: state.user.progress,
});

What would be the best to achieve this? The examples show no such use case.

Thank you again!

@letam
Copy link

letam commented May 16, 2017

You can do this if you're using the object rest spread transform:

const mapStateToProps = state => ({
  ...routeNodeSelector('about')(state),
  progress: state.user.progress,
});

Without the transform:

const mapStateToProps = state => (Object.assign({},
  routeNodeSelector('about')(state),
  {
    progress: state.user.progress,
  }
));

The very last example at the bottom of the README shows how this was reached.

@troch
Copy link
Member

troch commented May 16, 2017

You can compose routeNodeSelector with your mapStateToProps. The proper way to use routeNodeSelector is as a thunk, otherwise memoization won't work properly.

const mapStateToProps = (state) => {
    const routeSelector = routeNodeSelector('about');

    return (state) => ({
        ...routeSelector(state),
        progress: state.user.progress
    });
};

@cyberhck
Copy link

cyberhck commented May 1, 2018

hmm, I want to know one more thing:

const mapStateToProps = state => ({
  ...routeNodeSelector('user')(state),
  progress: state.user.progress,
});

what does the 'user' key do? I thought if I had user.list, user.edit etc etc, it'd give me only list, edit etc on route.name, but that doesn't seem to be the case, or am I doing it wrong? Or did I misunderstood routeNodeSelector?

@troch
Copy link
Member

troch commented May 1, 2018

routeNodeSelector is a memoized selector which only returns a new value (routing state) if the provided node name (in your case 'user' is concerned by a route change.

Your code sample doesn't leverage memoization because it creates a new selector each time, so at a result it behaves like a normal selector. It should be:

const mapStateToProps = state => {
  const selector = routeNodeSelector('user')

  return state => ({
    ...selector(state),
    progress: state.user.progress
  })
})

Do you have more context around your use case?

@cyberhck
Copy link

cyberhck commented May 2, 2018

ahh, got that part, as of now I'm having to do something like: const segment = route.name.split(".").length > 1 ? route.name.split(".")[1] : "index", I thought if I pass in user, it'd would return something like "create" instead of "user.create", but never mind :)

So I have to extract the routeNodeSelector and then it would use memoization? ahh, now I get it 😄 I didn't realize that before (actually didn't see it), it's a function which returns a function, but mine isn't. will do, thanks :)

@troch
Copy link
Member

troch commented May 2, 2018

Also I imagine you have another route node selector (or component bound to the route) above your routeNodeSelector('user')?

@cyberhck
Copy link

cyberhck commented May 2, 2018

yes, the index level, index has stuff like:

{
 user: UsersPage,
 settings: SettingsPage,
 about: AboutPage
}

and so on. On index page, I do routeNodeSelector("") and get the route, and I do split(".")[0],
about page doesn't have subroutes, but user and settings page have list, and user page has edit and create page, which are subroutes of initial page.

On UsersPage I do routeNodeSelector("user") then do a split(".")[1] (after handling undefined cases), then render List, Edit or Create page depending on segment.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants