Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing properties through a <Page ...> element. #98

Closed
chrisdew opened this issue Oct 29, 2014 · 5 comments
Closed

Passing properties through a <Page ...> element. #98

chrisdew opened this issue Oct 29, 2014 · 5 comments

Comments

@chrisdew
Copy link

I have some state in the top level "App" element (the one which renders <Pages ...>.

At the moment, the only top-level state is "logged_in", which is either null or contains the logged-in user's name. (The server also checks whether a user is logged in for sever-side page renders and REST API calls.)

I'm thinking of the top-level element's state as a client-side "session" - is this a problem?

I'd like to pass the "logged_in" state down into each page as a property, but to do that I think I'd somehow need to pass it through the <Page ...> elements.

Is there a method to do this, or is there a better approach to maintaining client-side "session" scope?

P.S. Another thing I'd like to pass to the pages (or rather just the Log In page) is a call-back to change the App logged_in state.

@STRML
Copy link
Owner

STRML commented Oct 29, 2014

That's fine to keep those things in the top-level element's state; something similar to that is generally done with Fluxxor.

There are a few options for passing that down through every element.

  1. Pass it as an explicit prop to every single <Page>, e.g. <Page session={this.state.session} handler={...} />. This is verbose but not as bad as it seems, it is nice to see where all of your data is coming from. I recommend doing this. The new 0.12 splat syntax can make this easier for multiple properties.
  2. Use the undocumented context feature of React. There's very little/no documentation about this. It's generally regarded as hard to maintain and I believe they're looking for a better pattern, so it could be removed at any time. If you're still interested, this more or less explains the syntax, although indirectly.

My top-level component uses the 'lots-of-wires' method. I mitigate it in some cases by using a Fluxxor plugin I wrote, but it's not a total cure. Lots of other users have come across this, though - here's some good thoughts on it.

@chrisdew
Copy link
Author

Thanks for your help. I hadn't realised that adding a property to a <Page ...> element would automatically cause it to cascade down into being a property of the element rendered by the handler.

Does this property-cascading behaviour hold throughout ReactJS, or is it a react-router-component special for <Page ...> elements?

@STRML
Copy link
Owner

STRML commented Oct 29, 2014

That's just for RRC - <Page> and <Location> elements automatically transfer props to their handler for ease of use. For other elements, their props are their own.

@chrisdew
Copy link
Author

Thanks, that explains it. I've chosen to pass the properties through the pages, and it works nicely.

<Page path="/commissioning" logged_in={this.state.logged_in} handler={this.state.logged_in ? CommissioningPage : createRedirect("/login")}/>
<Page path="/stats" logged_in={this.state.logged_in} handler={StatsPage}/>
<Page path="/login" logged_in={this.state.logged_in} set_logged_in={this.setLoggedIn} handler={LoginPage}/>

The last remaining issue is when a login-protected page (such as /commissioning) is rendered by the server, the server makes an AJAX request against its self for the top-level state. As this request does not come from the browser, the server does not see the logged-in session, and so doesn't tell the rendering part of the server to render a logged-in page.

I think this issue is more of a react-async thing, but if you have any insight here, it would be very welcome.

@chrisdew
Copy link
Author

Solution found: andreypopp/react-async#37

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

No branches or pull requests

2 participants