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

Migrating from react-redux-universal-hot-example #4

Closed
oyeanuj opened this issue Aug 16, 2016 · 5 comments
Closed

Migrating from react-redux-universal-hot-example #4

oyeanuj opened this issue Aug 16, 2016 · 5 comments

Comments

@oyeanuj
Copy link

oyeanuj commented Aug 16, 2016

Hi @xkawi! Thanks for creating this project!

I started my project with https://github.com/erikras/react-redux-universal-hot-example as well and was looking to potentially migrate to yours. It seems like the biggest change is around migrating to redux-saga and making it work on the server-side.

Are there any previous commits, guides or wisdom that you can share given that this project also started off from that repo?

Thank you!

@xkawi
Copy link
Owner

xkawi commented Aug 17, 2016

Hi @oyeanuj! Thanks for checking out this project.

Just want to clarify, are you looking for migration guide? Or what kind of guides that you are looking for?

@oyeanuj
Copy link
Author

oyeanuj commented Aug 17, 2016

@xkawi A migration guide would be amazing given that it could benefit a lot of people coming from erikras/react-redux-universal-hot-example#1184.

But if thats too much effort, I was hoping to see the previous commits of changes you made from the earlier repo.

I am particularly interested in moving from the custom clientMiddleware and action-creator conventions to redux-saga, and seeing how to incorporate it with SSR.

Any of it is appreciated :)

@xkawi
Copy link
Owner

xkawi commented Aug 17, 2016

unfortunately, I do not have any previous commits, though the short answer would be, I simply remove the duck pattern that resides in src/redux and put redux-saga's real-world example structure in.

Though I could share some insights that I had when putting things together for this project.

Since clientMiddleware and action-creator is replaced by redux-saga (you can literally delete those portions from the codebase), writing side effect requires only 2 things, the actions and saga routines.

To illustrate this, if you look at src/actions/index.js, there is loadUserPage function (dispatched at src/containers/UserPage) that returns action type of "LOAD_USER_PAGE". There is no other part of the codes that uses "LOAD_USER_PAGE" constant, except watchLoadUserPage function in src/sagas/index.js.

This simply means that, you have a saga routine that listen to action.type="LOAD_USER_PAGE" and trigger a few side effects afterwards (in this case, it load user's repos and starred repos, and update the state once result is received, which trigger the re-render). These side effects can be any logic, it can be making multiple network calls, handling the result of the network call, dispatch other functions, or update reducers, and so on. You can think of it like, when A event/action type is triggered, what are the things that need to happen? you answer this with a few lines of codes in 1 single function and 1 single file, src/saga/index.js.

This gives a better separation of concern:

  1. you write your dump components as per normal, and it only cares about the props and views
  2. you write your smart components (containers) as per normal as well, use redux's mapStateToProps to subscribe to some parts of the state, import some actions that are needed, import some components, and of course the page layout and everything, and you are done with your container. Containers should not concern about how side effects as handled, if should only concern about the actions needed (and when to trigger it), subscribing to part of the state (and pass down to dump components), and dump components required to form a page/layout.
  3. when writing your actions, you do not need to concern about how it will be used by others or how it will be dispatched. You simply define all the necessary actions for your project scopes, its types, and the payload. Usually you will know what are the actions needed when you starts to visualise and have a better sense of what the containers will be doing (e.g. a button to login, an edit post button)
  4. write the reducer as per normal in src/reducers/index.js (of course you can break the reducers down into separate files, so long it is combined and exported in index.js)
  5. last, and most importantly, your saga routines for handling side effects. In the most simplified terms, saga routines works in this way: it takes in (or listen to) certain action types, and trigger a series of side effects, and update the store for the view to update.

To learn more about writing saga routines, feel free to spend sometime picking redux-saga, their official documentation should be enough to get used to it. http://yelouafi.github.io/redux-saga/

In terms of configuring redux-saga into your project, you can simply follow its real-world's example structure. You write the createStore function, attached some middlewares, and so on. In fact, redux-saga is just a redux middleware.

The trade-off here is that, you do not have the "duck" pattern, where everything is categorised into modules. Though IMO, it is a reasonable trade-off, because it can give a better separation of concerns, hence a more maintainable codebase in my opinion. This is subjective of course, and it always depends on the project requirement at hand. I am also happy to share that, the project that I built base on this, have been deployed and maintained for few months now, and there isn't major hiccups so far.

In terms of migrating your existing project, my take would be - if it is too much headache - you can reimplement your project from the start using react-universal-saga as base, and slowly port over the dump components that are reusable, followed by the actions, reducers, an then the containers. Ensure that everything is working fine, where dispatching an action would update reducers and trigger re-render. After that, then you can explore more on how you can use redux-saga to benefit your project.

If all this sounds intimidating, feel free to explore other alternatives mentioned in readme. Think those alternatives are worth checking out as well. 😃

Hope this give some lights in migrating your existing project.
cheers.

@oyeanuj
Copy link
Author

oyeanuj commented Aug 23, 2016

@xkawi Thank you so much for this detailed guide! This is a perfect starting point, and what I was looking for.. I'll try it out and report back the results.

In the meanwhile, I'd love to see the categorization pattern you've mentioned and the project you mentioned here :

The trade-off here is that, you do not have the "duck" pattern, where everything is categorised into modules. Though IMO, it is a reasonable trade-off, because it can give a better separation of concerns, hence a more maintainable codebase in my opinion. This is subjective of course, and it always depends on the project requirement at hand. I am also happy to share that, the project that I built base on this, have been deployed and maintained for few months now, and there isn't major hiccups so far.

Thank you!

@xkawi
Copy link
Owner

xkawi commented Aug 25, 2016

@oyeanuj The duck pattern that I was referring to is this one: https://github.com/erikras/ducks-modular-redux

react-redux-universal-hot-example is using this pattern to structure its codes:
https://github.com/erikras/react-redux-universal-hot-example/tree/master/src/redux/modules

Essentially, react-universal-saga does not use this pattern, hence the trade-off I mentioned earlier.

I will leave this issue open for awhile, in case others would like to chime in as well.

@xkawi xkawi closed this as completed Oct 24, 2016
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