React Makes You Sad?
github.com
github.com
React itself is allowing me to write web applications faster and with less bugs, primarily because of the unidirectional information flow, but also because of the way it guides you into making everything components, which keeps the borders up between objects and makes testing easy.
Even better, I can now create both iOS apps and Android apps at the same time (I knew Objective C but not Java for Android), and at a much faster speed than before - the flex layout model alone has saved me days and weeks of debugging the iOS layouts in storyboards, and now I'm able to shift code between the app codebase and the web codebase with ease.
It is indeed overwhelming when first trying to learn React, especially when trying to learn Javascript at the same time, and this flowchart is so spot-on with the tendency to start using packagers, boilerplate, redux before understanding why they are useful.
Follow the flowchart, and you will find happiness!
One of my favorite examples of clean modular JS that does not depend on a framework is Mozilla's browserquest: https://github.com/mozilla/BrowserQuest/tree/master/client/j...
Many things that make life easier when making relatively small web apps also make debugging more complicated, compared to programming from scratch with minimal reliance on third parties. Choose wisely.
Are you referring to native apps, or do you mean by making a Web app with React you don't need to make native apps?
I am sad because every process rectangle in this chart should also point to a decision diamond that says:
"Does it seem that the entire industry has migrated to this stack, whether or not it really makes sense for everyone to? That a feedback loop now influences shops to choose these tools/technologies not because they are called for, but simply because they are trendy? That present excitement outweighs the question of 'whether you need this or not' in the eyes of most of your peers and colleagues? That the incentive to not get left behind is stronger than the incentive to stop and consider?"
And then, that diamond should point to a final rectangle that says:
"If you wish to remain employable, learn React + Redux + ES2017 + Webpack now, or join a different sector of the industry. As for the sadness, deal with it."
This isn't only true of React, of course. The underlying sadness comes from watching one's valid hesitations drowned out by the mob.
It definitely doesn't make sense for all types of websites, but React seems to me like a solid choice any time a) a true web application is desired and b) maintainability, interactivity, and scalability are high priorities. React isn't the best choice for static informational sites and such, but I can't think of an application that wouldn't be well suited to React.
A truly complex app where speed is crucial. [0] Like Atom. [1]
[0] https://aerotwist.com/blog/react-plus-performance-equals-wha...
I think the JS fatigue we're seeing is because web development is now largely a mature industry. React is roughly the 4th generation of Javascript technologies (1st = DHTML/Layers, 2nd = JQuery/Prototype/Mootools/YUI/Ext/Dojo, 3rd = Angular/Ember/Backbone, 4th = React/Polymer). At this point, there are millions of JS developers, they have seen multiple generations go by, and they just want some stability. The folks who always want to be on the bleeding edge are off doing IoT and VR startups.
IMHO, React is a nice piece of software, but it's a nice piece of software entering a market where existing solutions are already pretty good and much of the action is moving elsewhere. They have to hype it up, because people won't give up their JQuery/Angular/VanillaJS otherwise. It's a very different situation than when JQuery was introduced and web development was recovering from the .com bust and years of stagnation in browser innovation.
Sorry to be brutal but. Fuck no it's not. An hours studying of the JavaScript ecosystem should be more than enough for most to see that not only is web development not mature its mutating and beginning to try to consume other programming disciplines like some form of cancer. Just look at how NodeJS has been creeping its way from server to desktop to mobile.
It doesn't matter (for example) if I am/am not comfortable with ES2015 syntax. A junior developer already made that decision for me when he decided to implement the modal window by adding React, Babel, and Webpack to the project, instead of just writing a two-line event listener and a CSS class. Meanwhile, my colleagues are standing at the kegerator toasting his choice, because how could we ever have maintained or optimized such archaic vanilla JavaScript before without arrow functions and DOM diffing!?
React is not bad. In fact, it is great. But instead of being "an option" it is becoming "the default." Sadness results from being forced by industry trends into using it everywhere, despite knowing that it doesn't solve any problems that I did have while introducing new problems that I didn't have.
That said, I do still love React Native, and use React on a daily basis to take advantage of the "write once, run anywhere" paradigm.
I haven't used React or Mithril enough to speak confidently about the differences, but it seems Mithril offers everything React does and more with better performance and documentation.
https://code.facebook.com/posts/1014532261909640/react-nativ...
In practice you'll learn React Native once (1), learn some of each platform's intricacies (N), and sometimes need to debug (at most for each platform, so 0...N.
I can see that you haven't spent much time in the JavaScript ecosystem. And forget latest commit, if a JS project wasn't started in the last half year, it's already getting long in the tooth. After a half year, trendy devs will already start moving on to the next great framework and package manager.
Most of the "bugs" (or rather, limitations) in the issue tracker are either discussions or things that are difficult to address w/ the current codebase - e.g. design/ergonomics issues, as opposed to implementation issues - Those are part of the reason for the rewrite.
Another thing that is worth mentioning is that Mithril's general philosophy is to avoid adding features for features' sake, so it can look less "active" than it actually is.
That said, we still use it, but we're considering moving to React in the future, mostly since its learning curve is a lot less steep and we would be able to iterate faster.
The project, however, is quite serious.
You can also drop me a line via email, and I'd be happy to help too.
I think the issue comes from the learning curve between jQuery and Mithril. Coming to Mithril from React I'd imagine would be relatively easy, where coming to it from JS spaghetti would be rough due to the lack of adoption and step-by-step tutorials that exist compared to React.
In it, the guy first praises React to the heavens, then spends the rest of the session explaining all the ways they had to disable and work around React to get what they wanted with decent performance.
It seemed to me like their use case could have been done with jQuery in a few hundred lines. Maybe I missed something.
He also talks about writing code in a way that will work on both the server and client side, which is something you have to think about no matter what library you're using.
Does it though? I suspect their system is fairly brittle after all that "higher level orchestration".
I keep seeing this pattern repeat in different software disciplines. Unity is the same way: fantastic for prototyping, but often more painful in the long run.
It reminds me of a wise saying (can't remember the source) to the effect of this:
Javascript library user, day 1: "So expressive! So elegant! So easy!" Day 300: "Kill me now."
C++ library user, day 1: "How can anyone live this way?" Day 300: "Whoever wrote this was actually pretty smart."
In this case, a purely functional transformation from application state to HTML means you don't have to think about every possible transition between states like you would in a normal jQuery application. However, since you are not thinking about transitions, implementing transition animations will be harder.
I think the Redux guide itself (http://redux.js.org/) also does a fantastic job of a very gradual release into complexity. I recommend that anyone who feels they may want a Flux-like store read through the whole guide. It took me a day or two, but I found it to be extremely clear and enlightening.
The approach taken in the videos is great because it starts off with implementing your own simplified version of Redux and builds on that. There are no "magic" steps, this makes it much easier to develop an understanding of how it works.
The rest of the tutorials left me feeling frustrated not really knowing why. This one i just breezed through.
Without this tutorial we wouldn't be experiencing the ease and joy redux can bring to large react apps (We're currently porting a large messy Angular app to react piece by piece by replacing just leafs of the app at a time)
I know a few of those - folks who aren't beginners and who loved react to begin with, but are getting slowly disillusioned by the sheer volume of changes required to modify a data source or add a new widget.
Dropping flux or changing bundlers won't change the core of react... nor will writing any number of "helpful criticism" blog posts.
Complexity shifted from a mess of jQuery event handlers shuffling the DOM around to an intimidating mathematical abstraction in the form of functional programming.
The benefit is that you can reason about pure functions, whereas you cannot reason about a mess of intertwined event handlers.
Between to equally complex problems, react forces you to converge on a problem that you can actually solve.
Programming is hard. I think what's happening now is that we're starting to discover issues that were previously hidden by problems that are now solved.
All I want is are two simple configs. A dev one with a server/hot loader, and a prod one that concats/minifies. ES2015. That's it. That just doesn't exist out there. It's either no decent production bundler, or it's like 15 files and 900 lines of configuration that seem completely overkill.
I don't know. I don't have time to learn how the tooling works, but I also don't want a bunch of magic. Angular 2 is looking really good right now even with the (still very incomplete) angular-cli tool.
Dang. I just want my simple gulpfile back.
This seems to remove complexity but it just hides the complexity in the dependency. When something doesn't work out or he wants to change the behavior he still has to delve into these "15 files and 900 lines of configuration".
For something more approachable but less powerful check out https://github.com/insin/nwb.
https://github.com/edwardmsmith/react-starter
I didn't find the webpack stuff to be too overwhelming, and split dev and prod into two webpack files.
`npm start` to start the dev server and `npm deploy` for a production build. The production build produces two files - a vendor file that contains vendor code, and a client file that contains custom code.
It probably contains more than you're interested in (redux, tests, etc.) but it should be clear how to strip that out.
I highly recommend this blog post for anyone who is struggling with setting up React/Redux https://www.drivenbycode.com/getting-started-with-gluestick/
There's also a slightly annoying flicker when you type the last bit and it keeps returning the same movies.
I found react to be really complicated and heretical personally. I don't like mixing languages, but if I do, I would like them to be tightly coupled. I have started to mess with vue.js which is really awesome. Even in as a meta point it would be like:
> using vue.js? > give react a try again. It has changed a lot in 2 years.
If you're in production using it and still sad, or if you're not in production and not using it and still sad, move to the next step.
I understand encapsulation is necessary, but i wonder how feels working with someone who writes code with a shotgun next to him / her.
I'm sure there are plenty that like this rigidity, but for me, I'll pass.
When asked in #reactjs, they said that if you need access to a child's state you should put it into the parent, which makes sense but not in my case. There is a natural way of hiding working 'upwards' through the chain, but I can't say I've seen it ever work downwards like in React, and I found that rather frustrating and difficult to work around.
> this turned a 2 hour job into a 3 day job for me
> just trying to find a way
That basically summarizes my entire career with CSS/HTML/Javascript."Oh, the page you made looks great! Can you just move that image 10 pixels to the left?" Spend two days hitting my head on the desk trying to figure out why it won't align correctly
"Oh, the page you made looks great! Except in IE and the version of Chrome on Android 4.0.3" Spend two days trying to fix those browsers without breaking the others
Generally the way the bidirectional issue is solved is by closing the loop via dispatchers and stores. The child components send out actions to the stores, which then flow down through the parent, back in to the child. Turning what used to be a bidirectional flow to a unidirectional flow (sometimes at the cost of a bit of boilerplate for pre-existing components).
I guess the real question is, what is the use for the parent to be able to see the 'state' (the child components internal state)? The answer to that question (in my limited experience) has often been either 'to trigger an event (ex: save a form)' or 'so the parent can make some other rendering decision'. Both of which I've generally been able to solve via a flux implementation and possibly changing a 'state' into a 'prop' in the child (where the child gets a prop, some action is taken, and instead of changing state internally, an event is dispatched to the store with the new data, and the parent rerenders the child with the new 'prop').
But ultimately, hack it how you need. It's your code after all.
<YourComponent ref={yourRef => this.yourRef = yourRef}/>
I think you should be able to do this.yourRef.state, but if not, you can always implement a getState() method in YourComponent.You shouldn't merely learn React, but also unidirectional-flow architectures (like Flux, but there are many others, including better ones IMHO). Bidirectional data flow is a pain in the ass and once you understand unidirectional data flow, everything fits much easier. Of course, trying to shoehorn a bidirectional data flow in React is going to cause a lot of pain.
If you still need a bidirectional data flow, messing with lifecycle callbacks is definitely not the way to go. It seems to me you didn't have problems with React. You had problems learning React.
As your project grows, you'll come to see WHY small, dumb components are helpful, and how the top-down view manages the scope of rerendering.
You can come around to the espoused best practices organically.
As I said before, it's reasonable that some people are not going to like these particular best practices, and that in some instances it's going to get in the way.
As a concrete example, I just put up a form that is basically just a SSR datatables.net table and a save button. Adding react into the mix is literally unnecessary, and just adds boilerplate/extra code for no gain. In other words, it gets in the way. So I chose not to use it.
Its like saying lets use angular but not limit DOM manipulation in directives, build fat controllers that include direct requests to the server and business logic because all the service boiler plate is annoying and makes the application harder to reason about, and add objects directly to the global object because angulars dependency injection based on string values is error prone, not DRY, and kinda fool hardy, not use data binding because of the performance issues...
yeah those may be valid points, but if you buy into that you should just drop angular and use backbone or something else...
This is a conventional approach when working with the DOM, since the XML is organized as a tree. Plus it happens to work nicely with their intended data flow pattern. But you make an interesting point, what about UIs that don't fit nicely into the document paradigm? Are there cases where it would be better to organize UI components in a graph, for example?
> if you are working with a lot of third party components that are not react based, it can be hard (or a lot of boilerplate) to contain them within react applications.
In my experience integrating third-party UI components has been much easier than I would have guessed. The difficulty has not really been in wiring the React parts to the component's API, but in making a stateful third-party component behave in a stateless fashion.
What I'm objecting to isn't the idea that React's ideas aren't for everyone, or perfect for every application, but rather that React's issues somehow stem from some kind of Facebook-y need for "control". That's an especially weird claim to make given how simple and open-ended React (by itself) is.
There is no definitive documentation source (like msdn or angular docs) and every tutorial and guide came with its own massive set of boilerplates and libraries. These libraries did not have good documentation, either.
React-redux brings a fantastic way of thinking about the application, and I'm looking forward to seeing appropriate documentation.
Suddenly everything works out of the box, you get nice ES6 syntax out of the box, files structure is flexible out of the box - notice a trend?
Meteor and React is hands down the best way to use React in my honest opinion. Meteor 1.3 will come out very soon and will have full NPM and module support, after that I think Meteor will take the web by storm and become the defacto way to build modern webapps. None of this webpack silliness.
And this all happens for you automatically. No lie, React makes Meteor scale by virtue of how it forces you to architect your data usage.
Why are we as an industry suddenly so married to the idea that rather than evaluating other solutions we should just hammer away at React until it works for what we need?
I am still using 1.2.1, but I am excited about the more streamlined npm integration in 1.3.
For small pages / forms angular is in the sweet spot, so it depends on how your application is setup (not to say you can't do large apps.. but performance is harder in angular)
What is gained by building an app in React, and are there certain scenarios where it really shines?
1) I don't have to worry about whether a property should be observable or not. 2) When changing a property from non-observable to observable, adding parens to most (or all) references is a burden 3) Screens with a large amount of state become difficult to manage and reason about with knockout. Should I use .subscribe, .computed, .pureComputed etc. With React, call .setState, and write plain javascript for everything else. 4) Mapping large objects to observable view models manually isn't fun and the knockout mapping plugin isn't good. React deals with plain objects. 5) Knockout components perform poorly compared to react components with large amounts of data. 6) Knockout is not intelligent in the way it renders. If you replace the value of an observableArray, Knockout will completely re-render any piece of UI bound to that array. This is especially bad when paired with #5. React does a virtual DOM diff and only renders the bits that have changed. 7) With knockout, I have to concern myself with how to go about importing html templates into my components. React is javascript-only. Just use React.createElement, or JSX if you're OK with transpiling. 8) React tooling is infinitely better. I waste a lot of time trying to figure out why some binding is throwing errors in knockout. I've never experienced this issue in react, especially when using PropTypes. 9) Custom knockout bindings to implement 3rd party libraries can be an absolute disaster - especially when attempting to support 2-way binding. It felt like every custom binding I wrote in knockout was full of hacks and terrible code. I haven't felt this way at all with React, and I only have to worry about binding in one direction.
There is one thing though which I find results in subtil bugs (entirely my fault): When one input is changing and depending on that input another output value has to change than the input shouldn't change state yet and the output should be computed from input (+ state where necessary). Only then you should set the state.
Do not set the state before computing the output and don't compute the output from the previous state only. This will result in subtle and sometimes hard-to-find bugs.
this.setState(prevState => ({ prevState.count + 1 }))
This way all the changes will be stacked on top of each other correctly.Q: "Are you still sad?"
A: "... Consider another stack that better suites[sic] your needs (eg. Ember)"
The author has anticipated that react is not always the solution that is appropriate, and provided guidance in the case that react isn't actually a good fit for the project at hand.
class _MyActualComponent extends React.Component<reduxScafolding.Action & { myReduxState: reduxScafolding.ReduxState; pushPath: ReduxSimpleRouter.pushPath; } & { myActualProp: string; }, {}>{
//my component's implementation goes here.
}
/** type for casting (so consumers know the props they are required to pass */
class IMyComponentVisibleType extends React.Component<{ myActualProp: string; }, {}> { };
/** instrument my component with redux */
export var MyComponent = ReactRedux.connect(
(reduxStoreState) => { //subscripbe to reduxStore updates (Called every change).
return { myReduxState: reduxStoreState.myReduxState }; //map myReduxState to props
}
, _.merge({}, {}, { pushPath: ReduxSimpleRouter.pushPath }, reduxScafolding.action) as any //redux-binds, then includes the pushPath() method for use in our _App Component
)(_MyActualComponent) as any as typeof IMyComponentVisibleType;
ps: yes, about 3 lines of that is because I use Typescript. export default ({ name }) => (
<div>hello {name}</div>
)
With Redux connect: const SomeComponent = ({ name }) => (
<div>hello {name}</div>
)
export default connect(s => ({
name: s.user.name
}))(SomeComponent)you are using the lambda style components which is fine for simple stuff but for heavier stuff the class-style components are needed. also you are not passing the reducer actions, etc.
Still, what you are showing in your simple example looks pretty similar to the amount of boilerplate I'm seeing with Redux, so it looks like there's not really an easier way.
1. Much of it reads as"are you taking this approach? yes? don't take this approach. no? take this approach."
2. There are also a couple of flowchart errors ("are you working on a production app" appears twice for no reason).
3. The main reason React makes me sad is the need for excruciating flowcharts like this.
As a result, the entire thing comes across as self-parody. For context, I'm a developer who works on a large enterprise app with a full build toolchain (npm, babel, webpack, sass, etc ad infinitum).
Also, the "are you working on a production app?" has two nodes so that it can model the fork into {yes bundle, no bundle}, common in flowcharts.
If you use React in production and don’t use a bundler, you should. If you don’t use React in production and do use a bundler, perhaps you shouldn’t because it will distract you from learning process. Does that help?
The “need” for flowcharts like this comes from lots of misleading information on the internet about React, not from React itself.
Thank you for your comments!
But I also understand the reality of our field, where such things are very serious, and yet always verging on self-parody. I'm getting used to it.
Use React together with Redux, Webpack and Immutable (my suggestion).
http://teropa.info/blog/2015/09/10/full-stack-redux-tutorial...
1. Does react make you sad?
2. Refactor all your code.
3. React makes you happy.
I must agree that my own mess is far more comprehensible that someone else's. Until Old Code Syndrome strikes, anyway.
Future-you is going to look back on this comment and curse loudly.
The stuff is not open-source yet, but reading most of the comments here I wonder why anyone would want to open-source things? To meet the friendly people of HN? ;-)
You and I have different ideas of what battle hardened means.
Please read the official release notes when upgrading.
Nowhere does 0.14 say you need to change components to use classes. They are allowed now (since 0.13) but React.createClass() is still there and is not going away any time soon. I’m afraid you listened to bad advice.
1. Transitioning to 0.14 forced you to rewrite something (what? how? I assumed you meant transitioning to ES6 classes which wasn’t necessary but it seems like you meant something else)
2. What choice was it that you didn’t have? Just like 0.13, 0.14 (and 15 soon) allows you to use either ES6 classes or React.createClass(). Both approaches work and will keep working. What are you referring to?
It would really help if you could share at least a simple code example demonstrating your pain points. I want to help! Cheers.
Note that the community's ideas of best-practices, and all of the ecosystem around react is changing at an absurd pace, but core react is fairly stable.