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

Fix #1518: Move root route configuration to routes.js, add documentation for creating a global saga #1545

Closed
wants to merge 6 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Jan 30, 2017

Fix for issue #1518. The route configuration was previously split between app.js and routes.js. I've moved the App (rootRoute) configuration to the routes.js file, so it is all in one place. I also changed loading the root route to use getComponent, instead of component, to make it easier for people to implement a global saga if they want to do that. There is also new documentation on how to add a global saga. I've also updated the spacing for the route generators and tested them.

Original Pull Request Here: #1538

@ghost ghost changed the title #1518: Move root route configuration to routes.js, add documentation for creating a global saga Fix #1518: Move root route configuration to routes.js, add documentation for creating a global saga Jan 31, 2017
@gihrig
Copy link
Contributor

gihrig commented Jan 31, 2017

@RobertSheaO Thanks for cleaning up the PR! ✨

I'll be watching the discussion in #1518.

@mihir0x69
Copy link
Member

mihir0x69 commented Feb 1, 2017

This is awesome. Quick question- why is there no saga in App/? I had to remove sagas and injectSagas(sagas.default); from the route config. Precisely, from here to get it to work properly.

I love the overall idea. Although, there seems to be a working solution for this particular problem, this PR solves two problems:

  1. Creates a good, if not ideal, example for developers of implementing app-level sagas.
  2. Unifies route configuration in a single file.

That being said, I haven't studied other implementations. There's a nice comment from @justingreenberg but that involves installing redux-saga-router.

I'd love to know what others think of this.

@ghost
Copy link
Author

ghost commented Feb 1, 2017 via email

@mihir0x69
Copy link
Member

mihir0x69 commented Feb 1, 2017

@RobertSheaO No problem! :)

as not everyone will need it.

True. But IMO, moving some of the repo-loading logic in the global saga would demonstrate its use in a better way. It'll be easiers for developers to understand and adopt this approach if they see the actual code.

@ghost
Copy link
Author

ghost commented Feb 1, 2017

@KarandikarMihir I agree that a built-in usage example would be great. Not sure about repo-loading, since that only happens on submit; however, I could perhaps add an example of preloading @mxstbr 's repos on app load. Thoughts?

@gihrig
Copy link
Contributor

gihrig commented Feb 1, 2017

There's a nice comment from @justingreenberg

@KarandikarMihir The "nice comment" link got changed to JK's profile page ???

preloading @mxstbr 's repos on app load. Thoughts?

@RobertSheaO How about pulling the current GH star count for react-boilerplate?

@ghost
Copy link
Author

ghost commented Feb 1, 2017

Sounds good, I'll add that and update my PR

@marcandrews
Copy link

marcandrews commented Feb 3, 2017

Nice work!

So another option for app-level sagas, and user authentication sagas, which I think this PR solves, is using a Provider similar to how containers/LanguageProvider is set up and utilized.

While app-level sagas could still be useful, I think at least for user authentication, a Provider is a better pattern/implementation.

Thoughts?

@mihir0x69
Copy link
Member

@gihrig Sorry! Here's the correct link

@gihrig
Copy link
Contributor

gihrig commented Feb 3, 2017

There are a number of open issues surrounding difficulties with sagas and the way they are handled.

Ref: #1384, #1420, #1315, #1518, #1447 and this PR #1545.

I'm concerned about the lack of real-world experience behind these various proposals. The only two I know of having been applied are #1420 used in production by @adelsz and and #1447 used in production by @jeffbski, but not with react-boilerplate. @kopax has experience with #1447Comment and react-boilerplate. Perhaps he can update us with his experience so far.

I'm personally leaning toward #1447 (redux-logic) and possibly some combination of other proposals, but have not gotten far enough into this to make a firm stand. If anyone is interested, I have updated @jeffbski's fork to the 3.4 react-boilerplate release.

What I would really like to see, is for basic requirements of a simple addition to the example app to be drawn up, such as implementation of a simple login facility for example, then implemented in each proposal. I think the experience of those implementing the same set of requirements in the several proposed changes to RBP async handling would be enlightening.

more at #1554 - Thanks @marcandrews

@ghost
Copy link
Author

ghost commented Feb 3, 2017

I've been busy these past few days; however, I'll whip up an example to put into the example app. I'll also read over the above linked issues to see how they impact what I'm doing. Personally, I like the simplicity of this solution, since it uses sagas in the same exact way as all the other sagas. For my particular use case, this is how I am using them:

  1. Every route, except my login route, has an onEnter property that checks for a user token.

routes.js

...
const { injectReducer, injectSagas, redirectToLogin } = getAsyncInjectors(store);
...
{
  path: '/',
  name: 'home',
  onEnter: redirectToLogin,
  getComponent(nextState, cb) {
  ...
  },
}

asyncInjectors.js

function redirectToLogin(store) {
  return (nextState, replaceState) => {
    // Look into store for token, if invalid, replaceState with the `/login` path.
}
  1. Inside my App/index.js file that wraps the entire app, I check the token validity again, and if it's valid and I don't already have the data, I send the request to retrieve data using the global saga.

App/index.js

componentWillMount() {
  if (accessTokenIsValid) {
    if (!this.props.accountDetails) this.props.onLoadAccountDetails();
  }
}

@ghost
Copy link
Author

ghost commented Feb 3, 2017

@marcandrews See my above comment about using onEnter (react-router) for authentication. This happens at the earliest point in the app, the route config, which could potentially prevent executing unnecessary code for users who are not authenticated.

@marcandrews
Copy link

In the hopes of not detracting further away from @RobertSheaO and the awesome work he's done in this PR, I've created a separate issue #1554 in response to @gihrig's comment.

// create reusable async injectors using getAsyncInjectors factory
const { injectReducer, injectSagas } = getAsyncInjectors(store);

childRoutes : [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

childRoutes = [

Copy link
Contributor

@avdeev avdeev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to fix the doc


Like other sagas, your global saga will live within a container, the `App` container. Go ahead and add a file and use the following starter code; it's the same starter code for other sagas.

######app/containers/App/sagas.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

###### app/containers/App/sagas.js

```

Next we'll import the `sagas.js` file into our `App` route configuration by updating our `getComponent` function to asynchronosly load our files. You can just replace it with the one below.
######app/routes.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

###### app/routes.js

@magiccookie
Copy link

please merge

@mxstbr
Copy link
Member

mxstbr commented Jul 14, 2017

Deploy preview failed.

Built with commit 2e57793

https://app.netlify.com/sites/react-boilerplate/deploys/59690735a700c4681563d721

@coveralls
Copy link

coveralls commented Jul 14, 2017

Coverage Status

Coverage remained the same at 100.0% when pulling 2e57793 on RobertSheaO:dev into d292b17 on react-boilerplate:dev.

@justingreenberg
Copy link
Member

@RobertSheaO thank you so much for your contribution :) as we have just upgraded to RR v4 and refactored asyncInjectors, this should be resolved (please see #1746) — i would love your feedback if you have the time to pull down dev branch and take it for a spin! thanks again

@ghost
Copy link
Author

ghost commented Jul 21, 2017 via email

@circuitry2
Copy link

What happened to this? docs/js/global-saga..md no longer exists??? What is the recommended approach now?

@lock
Copy link

lock bot commented May 28, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators May 28, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants