The decorator-based approach sounds interesting, but (in my understanding) it will require moving the data fetching logic away from the main component into the decorator, which also creates a level of indirection that is intransparent to the component user, and I imagine stacking several of these decorators on top of each other should provide plenty of room for unforeseen side effects as well.
Personally, I think almost all components should be "dumb": They should just receive the stuff that they display as properties from their parent components and report changes back through callbacks. They should not perform any "controller logic" beyond form validation and input serialization. Only a few components at the top should be responsible for fetching and distributing resources from the backend. Typically, it should suffice to have an "Application" component that takes care of fetching stuff that every other component should see (e.g. data about the user), while components one level below the application should fetch stuff that is specific to the given page/view that is being displayed.
Unfortunately, compared to the humble beginnings a few years ago I feel that the whole React.js stack gets more and more bloated these days. As an example, managing state through Redux requires writing actions, reducers and implementing a subscriber pattern in my components, just to fetch some data from the server. I mean, if we're writing a version of "Photoshop" for the browser this level of complexity might be warranted, but in most cases we just want to fetch some JSON, display it nicely formatted to the user, let him/her click on it and possibly send some data back. If we need 500 kB of Javascript libraries to do that while having to patch/reinvent many other things that we took for granted before -like simple hyperlinks (I'm looking at you, react-router)-, chances are we're doing it wrong.
>it will require moving the data fetching logic away from the main component into the decorator
We are not suggesting you to do anything like this.
The article was about migrating from mixins to patterns like higher order components. If you do your data fetching right in the component, we are not suggesting you to change anything. It’s only mixins that we found problematic, and we are just sharing our experience migrating away from them.
>the whole React.js stack gets more and more bloated these days. As an example, managing state through Redux requires writing actions, reducers and implementing a subscriber pattern in my components, just to fetch some data from the server
Redux has nothing to do with the “React stack”. React is just React; if fetching data in components works great for you, why are you migrating to Redux?
>I mean, if we're writing a version of "Photoshop" for the browser this level of complexity might be warranted, but in most cases we just want to fetch some JSON
Redux is overused. Nowhere in the article do we recommend to use Redux. The article is about mixins.
Thanks for clarifying this! Maybe I misunderstood the example in the article that migrates the subscription logic from the component/mixin into the decorator. This was what made me question whether this will be more efficient/scalable than using the Mixin approach, as there is also some indirection here.
Concerning the whole Redux issue: Yes, of course I can -and do- use React without it, but the problem is that everyone else seems to rely on these tools and see them as an integral part of the "React experience". I find this problematic as it makes many components less portable, as they are bound to a given router / state loading paradigm.
I think it would be great if there could be a bit more emphasis on "keeping it simple" in the React tutorials, as I see a lot of (often unneeded) complexity popping up in the frontend world, and I think this will cause a lot of issues in the future.
>migrates the subscription logic from the component/mixin into the decorator.
It was not migrating the logic from the component. The example was about getting rid of a mixin. I think the article even mentions the opposite:
“If there is just one component subscribed to this data source, it is fine to embed the subscription logic right into the component. Avoid premature abstractions.
>the problem is that everyone else seems to rely on these tools and see them as an integral part of the "React experience"
Who is “everyone else”? I think you might be listening to a vocal bubble. As Redux author, I can tell you that it is not in any way essential to React. Some people use it, many people don’t. Solve your problems, don’t just follow what you see in flashy magazines.
>I think it would be great if there could be a bit more emphasis on "keeping it simple" in the React tutorials
Thanks again for clarifying, I don't want to criticize the work of the React authors or the community (which is outstanding), I'm just voicing what I observe from my "vocal bubble". Maybe I really spend too much time on HN :D
> I find this problematic as it makes many components less portable, as they are bound to a given router / state loading paradigm.
Interesting, I find if you "reduxify" everything, even the top most component becomes somewhat dumb and agnostic. With react-redux, it won't even be aware of the dispatcher.
Only if you have just one point where you _connect_ your components. If there are some containers deep in the tree then suddenly all your application is somehow tied to Redux. I've seen such recommendations from Dan to use connect often, but I find this problem a bit disturbing and not sure how (and if) to mitigate that.
I agree with your second paragraph very much. However, your third paragraph points out the adage that continually needs to be reiterated, and you kind of hint at it. If you are writing a basic app that fetches some json and displays it to a small group of users, then no, a framework stack like react/redux is not needed and you can stick to the basics. But when you have a complex application that needs to scale, react is a handy tool to help accomplish this task.
Furthermore, I think it's normal for react to bloat a little bit while programmers suss out new features and usage. However, hopefully paradigms will solidify over time and that bloat will start to deflate.. hopefully.
Data declarations via decorators for use by some data fetching layer sounds like exactly what I want.
> creates a level of indirection that is intransparent to the component user, and I imagine stacking several of these decorators on top of each other should provide plenty of room for unforeseen side effects as well.
Unforseen side effects ... that sounds scary! Though vague. Imagine there is some controller component (a currency conversion widget) and we're adding a dependency on "/exchange_rates.json". If we could add a hypothetical @getJSON('/exchange_rates.json', 'rates') at the top of the component declaration to make sure the "rates" prop is always either missing (loading) or present (successfully returned data, or an error response), that sounds great. It only takes ownership of one prop. Stacking decorators would work nicely. Am I missing the glaring avenues for unforseen side effects?
Personally, I think almost all components should be "dumb": They should just receive the stuff that they display as properties from their parent components and report changes back through callbacks. They should not perform any "controller logic" beyond form validation and input serialization. Only a few components at the top should be responsible for fetching and distributing resources from the backend. Typically, it should suffice to have an "Application" component that takes care of fetching stuff that every other component should see (e.g. data about the user), while components one level below the application should fetch stuff that is specific to the given page/view that is being displayed.
Unfortunately, compared to the humble beginnings a few years ago I feel that the whole React.js stack gets more and more bloated these days. As an example, managing state through Redux requires writing actions, reducers and implementing a subscriber pattern in my components, just to fetch some data from the server. I mean, if we're writing a version of "Photoshop" for the browser this level of complexity might be warranted, but in most cases we just want to fetch some JSON, display it nicely formatted to the user, let him/her click on it and possibly send some data back. If we need 500 kB of Javascript libraries to do that while having to patch/reinvent many other things that we took for granted before -like simple hyperlinks (I'm looking at you, react-router)-, chances are we're doing it wrong.