5 minute real-world performance test: I just upgraded a relatively large (200K+ LOC) app that performs server side rendering of charts from React 15.6 to 16.0. Render time dropped from ~50ms to ~15ms. The previous version was already optimized and precompiled (e.g. none of the process.env performance penalties were applicable).
Very impressive improvement for a drop-in upgrade! Especially considering the previous version was not considered slow at all given the complexity.
Could you compare your JS's bundle sizes before and after? I've heard that its little smaller, I've been wondering how much.
Edit: I've got it in announcement:
React is 5.3 kb (2.2 kb gzipped), down from 20.7 kb (6.9 kb gzipped).
react-dom is 103.7 kb (32.6 kb gzipped), down from 141 kb (42.9 kb gzipped).
react + react-dom is 109 kb (34.8 kb gzipped), down from 161.7 kb (49.8 kb gzipped
15kb shaved in production builds. Thats quite nice!
For Topicbox (which doesn’t use React, but that’s irrelevant), I decided a good signal to check was Object.values; if it’s missing, we include core-js. Thus, older browsers (IE, Safari≤10.0, iOS≤10.2, Chrome≤53, Firefox≤46 and Edge≤13?) will pull that in, but recent versions of all browsers won’t need the weight (the check is very light, and the overhead roughly `Object.values||require('core-js')`), and you have a solid and dependable ES6+ base to build on.
I assume you're then dynamically loading core-js when it's required? Dynamic module loading is something we've avoided so far, maybe we need to start looking into that.
Admittedly, this is an older browser at this point (Safari 11 formally shipped yesterday), but I remember it biting a workplace I was at 2 1/2 years ago & we had to polyfill Map and Set. I believe this was fixed in Safari 9.
I would like to report it on GitHub, but unfortunately I think it would violate my employment contract until I complete the process to get approval to do open source work.
Good realization. We were already using Map/Set polyfills in our apps so didn't notice the cost as much. I imagine it should be possible to polyfill with a much smaller footprint; maybe we can find another to recommend. As Dan notes Map+Set polyfills are also not needed in newer browsers.
If it's a Redux app, there'll be a lot of boilerplate in that. Not 200 KLOC's worth, but a fair bit.
I recently inherited a moderately sized Redux app with over 1300 source files! It's not a trivial app but it's not a word processor or videogame, either...
As a Redux maintainer, I'll toss out my obligatory reminder you can use as much or as little abstraction on top of Redux as you want. Don't like writing action constants by hand? Use `redux-actions` to generate action creators that have an overriden `toString()`. Don't like touching multiple files? Use the "ducks" pattern. Want something that adds additional layers on top so you don't have to write a lot of reducers and action creators by hand? Use Kea or redux-tiles or redux-scc.
I'll also post a link to the slides and livestream video for my React Boston talk this last weekend, where I talked about the Redux ecosystem and gave an overview of useful Redux libs that can help with various use cases: http://blog.isquaredsoftware.com/2017/09/presentation-might-... .
> As a Redux maintainer, I'll toss out my obligatory reminder you can use as much or as little abstraction on top of Redux as you want.
Tell that to the previous developer. To be blunt, if your library isn't very usable without helper utils or wrappers, it probably isn't really doing its job.
This is my first time using Redux, and my experience has been quite negative. This project has so many reams and reams of code that just doesn't clearly _do_ anything. Line after line of throat clearing and pseduostructure.
I accept that this may just be a poorly written application. I've looked over the Express code and that's not much better, which is remarkable given that all it does is proxy API requests. But all these action creators and reducers and constants seem to have added a lot of indirection to what is still thoughtless and illiterate code.
We are seriously talking about rewriting the whole thing. For a one year old project that's quite damning. Can you point me to an open source codebase that might convince me Redux-done-right makes for readable code?
Ask Redux users what problem it is solving for them and watch them squirm. Eventually they will come up with time travel debugging, or replaying state changes, etc. This is developers working backwards and inventing problems to justify their technical choices.
Not coincidentally, most blogs about Redux jump right into how to use it, without prefacing it with why would you want to use it in the first place.
A lot of developers think introducing more libraries and more rigor is a good thing even if it drives up the cost of software development. This is the only reason I can think of, for why so many people are using Redux. Another reason may be ReactRouter which makes it harder to supply data to React. But there are other MVC routers that make using React painless and I'd recommend to anyone considering using ReactRouter/Redux to consider better MVC-based alternatives. (And no, using MVC does NOT imply two-way data binding.)
I would flip that first paragraph around. Time travel debugging and replaying state changes are technical solutions that were created to help solve one of Redux's core use cases: making it easier for a developer to understand when, why, and how your state was updated, and what part of the application triggered that state update. In addition, centralizing large portions of your app's state enables a wide variety of useful capabilities.
I do agree that many people and articles talk about the "how" rather than the "why", but I'd say that this is a widespread issue rather than being specific to discussions of Redux.
Dan Abramov, Redux's creator, has said himself that "Redux is over-hyped". I also agree that many people are being pushed to learn it without understanding why they ought to use it, and that new learners are being told they _must_ start with Redux and React at the same time. That's not what we encourage officially - we suggest that people start with React first, then learn Redux later.
However, I think saying "people only use Redux because it's hyped or they're told to" is both inaccurate and unfair. I've talked to many people who have said that Redux is helping them write better-architected applications that are more maintainable and easier to work on. Some people may have chosen it due to hype, but many others have chosen it because it solves their problems.
Finally, I'd like to recommend reading Dan's article "You Might Not Need Redux", which discusses the tradeoffs involved with Redux, both the limitations it asks you to follow and some of the potential benefits you get in return: https://medium.com/@dan_abramov/you-might-not-need-redux-be4... .
>> making it easier for a developer to understand when, why, and how your state was updated, and what part of the application triggered that state update
What percentage of business applications would benefit from this? My guess is, very few. Typical business applications fetch data from the backend and display it, let the user update the data and immediately send the updated data to the backend. There is no need for something to track "when, why and how your state was updated and what part of the application triggered the state update". I am not saying nobody needs that kind of capability. I am saying that few business applications do, and yet there is this notion that React and Redux go together and if you're going to use React it would be strange to not use Redux. Practically everyone who uses React also uses ReactRouter and Redux.
The end-result of this is that React, which by itself is a simple, elegant and useful technology, has been turned into an over-complicated mess by the community of developers, by gluing it with over-complicated add-on technologies.
Why limit this to "business applications"? There's a whole lot more apps out there than just those :)
If an app is really _just_ fetching data, displaying it in a row or form, and sending it back, then there might not be a lot of benefit. However, if data is being shared across multiple pieces of a UI, and the user is interacting with that data in multiple ways, then there may be more benefit.
And yes, my own estimates are that roughly 55-60% of React apps are using Redux as well.
It's not the same -- Relay Modern and Apollo Data are both a bit half-baked still in terms of client-side state caching. GraphQL mutations are painful to code right now. I say all this as a long programmer on my side SaaS -- with a team, things aren't quite so bleak. I really want to go GraphQL but it's just too complex still. Redux is much simpler to reason about. It is a simple state store. The client side state caches are just not there yet from what I can tell. There is too much magic and not enough time on the market to trust my business with them.
I mean, I've seen people drop redux into a single stand alone form for no reason other than they hadn't used react before, so they picked up a tutorial and the first thing it said to do was use redux.
So, I'll happily agree that there's a whole lot of people using this without any need for it.
...but there is a need for it for some people, and for those people, what's your alternative? Raw react? Have you actually tried that? Passing all the props down from child to child to child to child? It's not awesome, I assure you.
Are there redux alternatives out there that solve the same 'single source of truth' problem I've never heard of?
What are you using?
> There is no need for something to track "when, why and how your state was updated and what part of the application triggered the state update".
...or is that simply not a problem that some people have? I'll certainly agree to that; but then, why are you using react?
If your UI isn't dynamic, why are you building an SPA? For fun? The good old MVC tech stack works perfectly well for static data display and forms.
You know why react exists? ...because complex interactive forms are hard to do right, and because interactive user interfaces that do something more complicated than CRUD operations are actually quite difficult to do right.
The MVVM pattern with data binding is the 'best' solution out there for most UI application framework, and react is successful specifically because it allows you to manage complexity by creating a hierarchy of components instead. That's a really powerful effective technique, there's no question.
Redux lets you manage the state for that hierarchy in one place. It lets you build large react hierarchies and know exactly what state the UI is in at any point in time, in one place. Why? ...because managing state in 100 different locations is complicated.
What you're seeing is tools to help manage complexity; but you only need to use them when your complexity reaches a threshold that triggers the need to use them.
If you don't have a complex problem, you don't need complex tools to manage it.
> has been turned into an over-complicated mess by the community of developers, by gluing it with over-complicated add-on technologies.
What you're seeing is the application of tools to solve a problem that doesn't exist for the specific domain you're looking at.
That doesn't mean they don't solve the problem; it just means your problem doesn't require that level of complexity management.
It's quite frustrating.
I hear the 'its too complex' as an argument from so many people about using libraries and tools, and want 'something simple' instead; but I've hardly ever heard someone pitch a viable alternative instead, just complaints. Too much tooling. Too much complexity. Over engineering.
So, tldr: When you do have a big complex react application with complex UI interactions... what's the alternative?
> Have you actually tried that? Passing all the props down from child to child to child to child? It's not awesome, I assure you.
I honestly think its not that bad. Elm essentially does that, and its arguably more productive than React's ecosystem.
You might just want to optimize things a bit by making non-leaf components take a simple "model" prop (that contains all the properties they need) to reduce friction a little, but aside for that it might even make code better by forcing a more thoughtful component hierarchy.
After all, if component A renders component B, then A really DOES depend on B's props. Magically having B kinds of hide dependencies.
After all, short of using DI containers, if I have a function that calls another function that calls yet another, I DO pass arguments all the way down. And React components are semantically just functions.
Only at a relatively trivial scale; and certainly, do that if your application is simple enough. There's probably a fair number of applications that clearly fall into the 'simple enough not to need redux' category.
That's a good approach, seriously. You don't need redux at that point; don't use it. I'm not even suggesting such applications are 'trivial'; they probably just don't have excessively complex component hierarchies and interactions.
This is an argument that has literally been made a hundred or more times before, and nothing has changed about it.
Sure, this article is about dependency injection, but its essentially the same domain. You can argue that manually passing props is the same of 'poor mans' dependency injection, and it certainly has value in that there's 'no magic' in it.
...and certainly, you fall into the pit of pointlessness and frustrations when you use magic, but there's no convention to make the magic 'all work without surprises'; but the same issues still apply.
Once the application reaches a certain size, the maintenance burden of the 'simple' approach becomes prohibitive.
I am evaluating whether or not to use one of these state managers (vuex in my case) at the moment. I looked over the original facebook talk about flux and I am kind of getting the feeling that this is one of those solutions to a problem I don't want to ever have. It isn't about how complex your app is, but rather, how complex your organisation is.
A lot of these solutions, like static typing in non-performance areas, and so on, are about "how do we get this new engineer to start working on code that he has no idea about quickly". This problem only exists in large organisations and I personally don't think large organisations are very good at anything so don't care about those set of problems.
Basically it comes across as another "how do we hire large numbers of average programmers" problem and the facebook talk said exactly that. State managers, like dependency injection, just add another level of indirection that make your application harder to debug. You can no longer just follow a simple chain of methods, because everything disappears into the magic land of the state manager as soon as you start using (as the vuex example) store.commit("increment", 10); instead of actual methods and so on.
I'm not going to continue repeat the arguments which have been made exhaustively about the benefits vs. draw backs of these approaches by other people. There are plenty of articles which cover this topic... all I can say is please read them.
If you still don't see any value in these tools, don't use them.
All I'll say is this:
In my experience, people tend to consider their applications to be simple enough that a simple solution is sufficient.
However, in reality, that seldom seems to be the case.
UI is hard to get right, and has a tendency to drift towards complexity over time as more features are added: I can think of several people who have picked the naive simple solution and regretted it later; to the point of rewrite in some cases.
People who picked the complicated solution sometimes regretted the extra burden of complexity, but I don't think I've ever seen this as a cause for large scale failure or rewrite.
I agree. I have written large applications with client-side rendering and they do get very complex. I am still just trying to debate the topic rather than claim to know the answer.
You also have to figure out how you are going to deal with debugging access to the state. Sometimes you don't even know who is modifying the state. Add in asynchronous programming, and you have all kinds of modifications going all in all kinds of orders from all over the place and you have to figure out:
the order of the modifications
who performed them
how they modified them
So the state manager adds that in as well. You can add getters and setters and enforce synchronous programming in certain methods, but then you are 90% towards a state manager.
For me, there's a peace of mind associated with knowing that all my state is in one place in an organized format. It's like having a db, but on the front end, and it makes testing the front end very nice. It also has other practical benefits.
Specifically, 1) it makes rapid iteration simpler because I don't have to click back to the portion of the app that I'm testing but can instead just rehydrate a cached state, and 2) it makes it trivial to save state for the user either by caching it locally in the browser or by sending it over to the back end.
I'm working on a fairly small but still nontrivial React app for work (it's the first time we've used React for anything here, and we're partly doing it to evaluate React for future work). I've not used Redux anywhere in my application (it's all vanilla React), but my state is still all in one place in an organized format, and, since I have a single component managing my state, I can still trivially do both (1) and (2) there.
What's Redux giving me that I don't already have, aside from another layer to maintain and another piece to break?
Quick summary: you don't have to pass data as props all the way from the top of your app to the bottom, and it lets you keep your app state if you're doing hot module reloading in development.
In addition, time-travel debugging and the action history log really are powerful tools for understanding how your app is behaving over time.
My other comment just below this discusses some more benefits, and links to Dan's "You Might Not Need Redux" post. I'd encourage you to read that as well.
The React docs generally advise that apps try not to use context directly, as the API has limitations, and _will_ change in some future React release once they figure out a better approach. The main issue is that context updates are blocked if a component returns `false` from `shouldComponentUpdate` (and the same for a PureComponent). As a result, context is best suited for references that won't change, such as pubsub event emitters.
Michel Weststrate's post "How to safely use React context" [0] is excellent, and Ken Wheeler just gave a good talk about context at React Boston [1].
As someone who went from using context to using redux, you can really shoot yourself in the foot with contexts. With redux we can breath again.
Contexts is useful for anything that rarely changes. Like callbacks. But if you want to send down stateful things it will quickly become a mess for complex apps.
"I don't need redux because I implemented something to do the same thing it does myself" is not an argument against redux. You may not like redux but you do understand it's doing something necessary, so people who like it's implementation should probably use it.
eh. Not really. Because there is no schema, what happens is the Redux store turns into a mess.
You got 10, 20, 30 developers working on an app, no one has a clue what any of the Redux variables mean or what use-case they are for (or what use-case they may change), and worse you have redundant data scattered everywhere and you're never sure which should be the authority. It's an ad hoc global variable soup that is updated with the moral equivalent of GOTOs (Redux actions) that litter the code in just about everywhere you could possibly think of.
I like Redux because tracking mutability and specially, side-effects that cause it, is a bitch once your app stops being a special snowflake you alone created and cared for a small purpose.
Even for those small applications/prototypes, having a centralized store allows me to code on auto-pilot where I don't have to worry as much about the code and focus on what it does instead. Would X particular piece of UI work better in a different way? Okay, then that UI code can fuck right off; it's not like it's going to affect the rest of my application's state.
You might also want to look at what people used before redux. There were a lot of Flux libraries and they were not all easy to use. And skipping libraries for state management all together often ends up in writing spaghetti code or reinventing the wheel. A small state management library can help a lot.
I used a Flux library before but like mobx now and will default to that unless some specific requirement point to redux or something else.
React is nice because it encourages encapsulation and componentization. Redux feels like it discards all that. Your OO encapsulation gets disassembled into pure functions and dumb state. Pure functions are great to reason about, but redux applications feel like they have their insides extruded and thrown everywhere.
I jumped in the Redux bandwagon after spending the decade before that either in jquery hell (or pre-jquery hell), and eventually Backbone, Angular, and React + Flux.
I've touched probably 200+ production frontend apps of various sizes by now, ranging from a couple of pages, going to tens of millions of lines of Javascript in a single monolith.
Your millage will vary and everyone hits different challenges in their career, but to me, the biggest issues when building apps was never building them from scratch or adding new features. It was always maintaining existing features. So I optimize everything I do for that, as I consider everything else completely trivial except for groundbreaking algorithms designed by PhDs (which is not me) and not worth thinking about.
I've spent years trying to nail down why these apps, no matter who works on them, always end up impossible to deal with. No matter how much time is spent trying to figure out the architecture, documentation and design, it always goes to hell given enough time.
To me (and its a totally personal analysis), it was always nailed down to figuring out: "Where the F* does this value come from" or "how do I follow what the hell this button does". It should be simple. I can use a debugger, obviously, but as requirements pile on, it invariably goes to hell.
Elm, to me, is the panacea of solutions here. A single atomic state, and a UX that is nothing more than a projection (or a map, if you prefer) of state to UX.
And to keep the UX "dumb", you then need to externalize all state and side effect logic.
Once you have that, you can reason about any bug without even looking at the code. Is the UX wrong? Was the state right? No? Did the event triggered right? yes? Well, the bug HAS to be in the update function. Boom done.
Now the question becomes, how do you reproduce this in JavaScript, which doesn't even have an approximation of algebraic effects, doesn't have immutable data structures, doesn't have a good way to play with the dom in a declarative way...
React + Redux with a few extras from the ecosystem provide that. Who cares about boilerplate, I get predictability. The more you abstract, the less predictable things get and bugs can come from anywhere.
Inevitably as the app grows, you need to add stuff and weave it in the existing features. The decoupling of State <--> Selector <--> Component <---> Action <---> Reducer has a very tightly defined set of semantics where even the most complex requirement fall neatly in these atoms (not quite as neatly as Elm when it comes to side effects, but it's as close as I've found for now).
Build an app some other way that does the -exact- same thing? You'll either end up with just as much code (oh, it won't be as repetitive and boring, but it will be there. I LOVE boring code), or you'll end up with something much more rigid that requires more compromises. There's a few alternatives that get close, but they usually do so by tightly coupling concerns and making it harder to figure out where the hell shit is happening.
The only obstacle is that the reasons behind "why" things are done this way is almost lost to most people working with Redux, in spite of Mark's best effort to prevent it from happening (there's only so much he can do short of brainwashing the planet). When the "why" gets lost, the community starts building things that neuter Redux, making it seemingly useless vs the alternatives.
I have to say this near perfectly mirrors my experience. We have a JS application [1] that is getting fairly large in size and development is moving quickly. Before we introduced React + a Redux style pattern (we don't actually use the libraries but have borrowed heavily from the pattern) we did find it difficult to track down bugs and making changes to existing features became a minefield.
I feel the pattern has helped as the team has grown. Yes there is boiler plate, but that boilerplate makes it hard to deviate from the pattern e.g. if you want to update the application state, you must dispatch an action, no way around it. In the past with MVC/MVP style patterns responsibility get muddled and you get a lot of inconsistency in implementation.
I've got no data for it, just observations, but since we have switched a to more functional style of programming and using immutable data, we are encountering less bugs which I put down to side effect free code.
Overall we have had a positive experience with React + the Redux pattern. Yes you could do this with other frameworks and patterns, but it works well for us and no doubt the same argument could be applied to whatever framework others are currently using.
The TL;DR is Redux tries to place a set of constraints on how and when you're allowed to share state between components and how and when you're allowed mutate that shared state, much like how React and it's virtual DOM abstraction places constraints on how and when you're allowed to manipulate the DOM.
These constraints allows the library to make certain assumptions about state and state changes that enables it to perform global performance optimizations across the entire codebase (namely performing only shallow equality checks on all state-mapped props when determining whether or not to rerender, because it can assume all state changes will result in a reference change) that would otherwise have to be performed for each component on a case by case basis, and micro-optimized by each individual developer by hand.
These constraints also allows tooling authors to make these same assumptions, which is what enables the best-in-class tooling that Redux developers have access to, like time traveling debugging and state change replays. These tools would simply not be possible to build in a generalizable way if your codebase didn't allow them to make the same assumptions (and adhere to the corresponding constraints when it comes to state sharing and state mutations) as it could for a Redux codebase.
The post has a whole list of very compelling use cases/tooling that are either made possible by or at least made completely trivial by the enforcement of these constraints around state mutations:
> These limitations are appealing to me because they help build apps that:
> Persist state to a local storage and then boot up from it, out of the box.
> Pre-fill state on the server, send it to the client in HTML, and boot up from it, out of the box.
> Serialize user actions and attach them, together with a state snapshot, to automated bug reports, so that the product developers can replay them to reproduce the errors.
> Pass action objects over the network to implement collaborative environments without dramatic changes to how the code is written.
> Maintain an undo history or implement optimistic mutations without dramatic changes to how the code is written.
> Travel between the state history in development, and re-evaluate the current state from the action history when the code changes, a la TDD.
> Provide full inspection and control capabilities to the development tooling so that product developers can build custom tools for their apps.
> Provide alternative UIs while reusing most of the business logic.
You could certainly make the case that Redux is not necessary for building a React app. Or the case that the additional boilerplate and constraints it places upon you could be a net negative for apps that are not sufficiently complex to warrant them. In fact, that's exactly the case that the linked post tries to make.
And yes, the only reason people use Redux is to introduce rigor (constraints) into their codebase and development workflow. But to insinuate that the rigor and constraints introduced by Redux will only ever be a net negative in terms of developer productivity is to display a fundamental ignorance regarding the vital role that rigor and constraints have always played in software architecture, and the fact that the recent advances in frontend architecture that have been proven to reduce complexity and make large codebases easier to reason about (things like the virtual DOM, unidirectional data flow, immutable state trees/caches, functional/reactive programming, and even the MVC pattern itself) have almost always come as a result of placing more constraints on what the developer is allowed to do.
I'm sorry to hear that your experience has been negative so far.
There's a commonly repeated phrase that "Redux is a pattern, not a framework". Redux doesn't have anything built in for actually updating the state, or defining an application architecture. Redux primarily provides a pattern for separating the write logic from the rest of the app conceptually, and adding centralized behavior on top of that via middleware and store enhancers. So, how you build and organize your application around that pattern is up to you.
Similarly, Redux does not _require_ that you use action creators, action type constants, or that you separate everything into multiple files by code type. Those are common _conventions_. It's absolutely legal for a Redux-connected React component to do:
this.props.dispatch({type : "ADD_TODO", text : "Buy milk"})
However, there _are_ reasons why those patterns exist in the first place.
So, a few thoughts. First, I'd encourage you to take the time to read through my two-part blog post "The Tao of Redux" [0], which goes into detail on the history and design of Redux, the intent for how it _should_ be used, and why common usage patterns exist.
Second, while I don't have a specific Redux codebase to point to as a "shining example of best practices" strictly off the top of my head, I do have a list of some selected Redux applications that may be worth looking at. Some of them are purpose-built examples, and others are "real" apps. See the list at [1] - I know that there's some good codebases in that list. I'll also suggest taking a look at "Project Mini-Mek", the sample application for my own blog tutorial series [2].
My React/Redux links list has a large section of articles discussing good Redux architecture and best practices [3]. Some of those articles might be helpful.
Finally, I'd be happy to spend some time discussing your current app's codebase, and perhaps offer some suggestions on ways you can make it better or easier to deal with. HN isn't a good place for that. However, I spend most evenings hanging out in the Reactiflux chat channels on Discord. Please feel free to ping me there, and we can discuss things further. The invite link for Reactiflux is at [4].
Sure. And please really do feel free to ping me on Reactiflux if you have questions or would like to discuss things.
Redux isn't for everybody or every use case. However, I do think it's frequently misunderstood. If it _really_ isn't helping you solve your problems, then you should certainly use something that's more appropriate or useful. But, it's also entirely possible that a better understanding of how it can be used, or how it can be adapted for certain situations, might make it more useful and helpful for your use case. A lot of my time writing about Redux has been spent trying to help clear up misconceptions, answer questions about real-world usage, and help people better understand how it works and can be used, so that they can make more informed decisions about Redux.
Do you recommend people to use redux for small scale project for global states? I for example use redux for states like isUserLoggedIn or userName/userId, and not much else. If not what are the alternatives apart from simply passing the state down the component tree? Thanks.
If that's really all you're tracking, then you're probably not going to get much benefit out of Redux. Then again, it's also possible that there wouldn't be much overhead in simply creating a Redux store, inserting a couple values, and connecting components to retrieve those.
Dan's post "The Case for Flux" [0] discusses what kind of use cases would benefit from a Flux architecture. That still very much applies to using Redux as well, and is worth reading. The Redux FAQ also has a section on "When should I use Redux?" [1]
There's nothing _wrong_ with passing down values as props, even through multiple levels - it's just that most people dislike doing so. You could make the values available using React's "context" feature, although it's likely that wouldn't be the best choice here. There's also a variety of "not-quite-Redux" libraries out there that try to simplify the interactions with Redux ("no reducers", "no dispatching", "no actions", etc), and perhaps one of those might be useful.
Redux is unusable without an insane amount of boilerplate. HOWEVER, I think Redux still is an improvement over raw JS, although underpowered compared to Elm.
It seems like it is essentially trying to bring functional union type case switching to a language without that feature. As such, actions are insanely laborious to construct. Furthermore React / Redux is far to pedantic in reinforcing it's design decisions without offering a backdoor to work interact with the outside world.
Mostly that updates can only happen on explicit changes to the state. Also a React application doesn't acknowledge the possibility of a component existing which is not a React component. I most recently ran into this issue when trying to add an OpenLayer map to an application. In a vanilla JS application it's trivial, but React was difficult to coerce into breaking it's own rules to accommodate it.
Elm solves this particular issue well with Ports [1]. It respects the possibility that there may be things going on that haven't been explicitly planned for.
actions are insanely laborious to construct
On a second read through, this is edging on hyperbole. Maybe a more honest presentation of the facts is that Redux actions grow tedious to write. You start with an action type declaration:
export const SOME_ACTION = "SOME_ACTION";
Then you create an action creator:
export function performSomeAction(data) {
return {
type: SOME_ACTION,
data
}
}
And then of course you need to write a case statement in a reducer to deal with the data and somehow effect the state.
It's tedious because it's trying to recreate the pattern matching functionality of passing union types around in functional languages. In SML, Haskell, Elm etc. you can elegantly decompose and consume types with case statements and pattern matching, which are built into the languages [2, 3].
I'm not sure I follow your first point. What's the meaning and issue with "updates only happen on explicit state updates?
Per the "non-React components" aspect: wrapping up non-React code into components is actually something React is pretty good at. The typical implementation of a maps lib wrapper component would have React render a single div with a ref, then use `componentDidMount` to initialize the plain JS lib and hand it the div. From there, the lib can attach any extra elements it wants, and React won't care. React's lifecycle methods like `componentWillReceiveProps` and `componentDidUpdate` are used to call the imperative lib APIs, and the lib would be cleaned up in `componentWillUnmount`. I wrote a blog post that demonstrates using React components to wrap up the Cesium 3D globe library [0], there was a great talk at ReactBoston that shows doing the same for Mapbox [1], and I have links to other similar articles about interacting with non-React code [2].
Per my other comments elsewhere in the thread, it's up to you how much abstraction you want to use for actions and reducers. A common suggestion is the Redux-Actions lib, which provides utilities for defining action creators and reducers. You can even use the action creators themselves as the "constants" for the reducer cases, since they have custom `toString()` methods.
Also, switch statements aren't a requirement either - they're just the most obvious way of handling multiple values in a single `action.type` field. You can write whatever conditional logic you want in a reducer.
All that said, I do agree that the JS language as a whole does not have the built-in pattern matching capabilities that other languages have.
I didn't quite get redux when I first (had to) use it, and I still wonder if I'm doing it wrong, because I do 99% of my dispatches with one simple action.
I ended up making a dead-simple merge(oldObj, newObj) function that's halfway between Object.assign({}, ..) and lodash.merge() (it doesn't merge arrays)[0]. It makes it easy for me to update deeply nested state trees, provided the nested data is simple enough.
As a result, 99% of my dispatches uses one action type, PLAIN_MERGE, and a dumb state tree indicating what I'm updating, like so:
That might be some deep nesting, but it actually reflects the structure of the interface too, so it's kinda self-documenting.
The associated reducer is simply return merge(state, action.state). Again, maybe I'm missing something but it seems like a pretty simple and effective solution to me?
That's a technically legal use of Redux. Redux doesn't care if you have an action object that only contains a type + some values and do all the work on the reducer side, or precalculate the new state before dispatching the action and have the reducer simply blindly merge in whatever was provided. Redux simply calls the root reducer function, and saves the root state value it returns.
There's actually prior art for what you're doing (per the articles at [0] and [1]). The code will work, and the changes should show up in the Redux DevTools. Dan even described that as a possibility in some of the earlier Redux issues ([2], [3]).
Now, having said all that: I _personally_ would say that a "single SET_STATE action" approach goes against the intended spirit of Redux. One of the core principles behind Redux is that it should make it very easy for you to understand when, why, and how your state was updated, and what part of the application triggered that state update. If you only have a single SET_STATE action type, then reading the action history log in the DevTools won't tell you much useful. You can see the action contents and the diffs, but the action log itself won't have any semantic meaning, and you can't easily trace back to where the action was dispatched because the entire codebase is dispatching the same action type.
Redux also doesn't care if you do "setter-style" action naming like SET_USER_NAME and SET_USER_ADDRESS, or "event sourcing"-type naming like "USER_ATTRIBUTES_UPDATED". However, either of those approaches is going to at least provide _some_ semantic meaning, making the action log easier to read and the origin of the action easier to trace.
I'd encourage you to read through the "Structuring Reducers" section in the Redux docs [4]. In particular, the "Normalizing State Shape" page [5] talks about why we recommend normalizing your data into a flatter structure, rather than keeping it nested.
Finally, you might want to read through my two-part blog post "The Tao of Redux" [6], which goes into detail on the history and design of Redux, the intent for how it _should_ be used, and why common usage patterns exist.
Prior art is relative :P. This was the solution I came up with in October last year, after a summer of struggling to pick up React and Redux. I suspect half of these articles either didn't exist or were impossible to find when I started, so thanks!
> when, why, and how your state was updated, and what part of the application triggered that state update.
Well, when I said "single" action I was fudging a bit; I have a switch statement with a dozen action types that all are equivalent to the PLAIN_MERGE action. The point is more that I don't have much code inside my actions and reducers, except for the stuff that needs to see the "whole program state" - everything else tends to be encapsulated inside the components.
Also, I think you overstate the lack of semantic meaning: that state tree I pass along, together with the occasional custom action type tag, tells me exactly where the dispatch originates from. Of all the problems I have when debugging my app, finding the source of the dispatch is never one of them.
I dislike this attitude. That list is not exhausting, it's a list of specific tools that solve specific problems, if you don't have the problem don't concern yourself with the tool.
- I don't already understand how an app using redux works when it reaches a decent size; therefore don't know what problems it will have and need to learn more
- I can't start using redux to understand those problems without making important architectural choices early on, i.e. between sagas/thunks, ducks/not-ducks, or how to remove duplication from reducers, because the community has so many parallel solutions to any given problem; therefore, I need to write a toy app instead of using it on a real product
- redux on its own seems to need about ten packages before you can load information from a json api and pass it to react, a task which is the basis for most toy apps; therefore, every toy app I write seems bloated and heavyweight
What sort of issues are you running into as far as "how an app using Redux works"? For myself, the first thing I usually do when looking at an unfamiliar Redux codebase is to look at the store creation logic, see what middleware packages are being used, and see where the root reducer logic is being imported from. Then, I skim through the reducers to get an understanding of what the state structure is, what kinds of values are being stored, and what some of the reducer operations are.
I'm not sure why you say that "you need 10 packages to load JSON data". Assuming that you're in a browser that supports the Fetch API, you need _no_ additional packages at all. You can make an AJAX call in a connected component, and call `this.props.dispatch({type : "DATA_LOADED", payload : response.data})` in the success handler.
Now, we do encourage people to try moving that logic out of components to make it more reusable, which usually means using thunks. However, redux-thunk is all of 12-ish lines long, and if you'd prefer not to actually add it as a separate package, it can easily be pasted into your app directly. But, you genuinely shouldn't _need_ more packages than that to be making AJAX calls. There's plenty of additional abstractions that are available around making network requests and processing the results, but those are all purely optional.
Sorry, I was a bit ambiguous and whiny in that post. What I mean is that there's a paradox of choice when trying to work out what best practices for Redux are, after running through the docs but before building something. When there are five good solutions to a problem, and none are canonical, it takes five times as long to choose one.
Yeah, as with React, we've tried to leave the choices up to the community. This is great for some people who prefer to make choices, but not as good for others who want to be given a direction to follow.
Besides the other "discussion about abstraction" issue I just linked in another comment, I also recently opened up issues to discuss general docs improvements [0] and a rework of the "Ecosystem" page [1]. I really would like to have some docs sections that give more opinionated advice for topics such as "what side effects lib do I use?". Unfortunately, my own free time is already very limited, but I would _love_ to work with people from the community to add new docs sections and update the existing ones.
I also agree that there's a bit of a gap between the "TodoMVC" level and the "building a full-blown production app in the real world" level, in terms of docs and advice. I'd love to see some new docs sections that help with that aspect as well.
So, genuine request to you, and any other readers/Redux users out there: if you are interested in helping improve the Redux docs, PLEASE let me know! Ping me on Twitter or Reactiflux, file an issue, or leave a comment on an existing issue, and we can figure out how you can help us make the docs better and make it easier for people to level up along their Redux journey.
> I don't already understand how an app using redux works when it reaches a decent size; therefore don't know what problems it will have and need to learn more
This sounds like a problem of inexperience (which is a problem everyone faces when using a new tool). If you've never used Rails, you're not going to understand the long term implications of maintaining and scaling a complex Rails application. If you want to know what problems you will encounter, you'll have to read a book or learn the hard way, the same as any other tool.
> I can't start using redux to understand those problems without making important architectural choices early on,
This means you're not experienced enough with redux to be making those choices and that's ok; use an alternative tool that you understand well, hire someone with the relevant experience, read a book, or understand that you'll have to do some refactoring later on if you make the wrong choices today.
> redux on its own seems to need about ten packages before you can load information from a json api and pass it to react, a task which is the basis for most toy apps; therefore, every toy app I write seems bloated and heavyweight
This is not correct, but also "not even wrong" in the sense that this concern is outside the scope of redux. If you want to use a bunch of redux related data packages that's fine, you're also free to use GraphQL, Backbone, fetch, jquery, webosckets or straight up XMLHttpRequest. When I hear "I need 100 packages just to do X" it's usually a sign to me that the developer is somewhat inexperienced with the ecosystem and tends to defer to a package whenever they need to solve a problem; this is usually the wrong approach, it's like someone complaining "I need 10 packages just to do string padding"... well no, you don't, just write that code yourself.
> It's a hard ecosystem to bootstrap yourself into.
So is cross-platform game programming and there are hundreds of different engines, toolkits, SDKs, editors and other utilities spread across a dozen different languages. Which one should you choose? I don't know it's all too confusing, they should just stop making new tools so I can catch up.
> This means you're not experienced enough with redux to be making those choices
This is the fundamental problem. In order to learn Redux, you need experience with it. In order to get experience, you need to work with Redux. In order to work with Redux, you need to learn it.
You use the example of Rails, but Rails is the poster child of opinionated frameworks. For someone trying to learn it, there's no ambiguity about how a project is structured. The same is true of Unity or the UDK: there's a single tech choice to make, after which you can rely on the framework to guide you.
I understand that the js community prefers small composable libraries, and agree with the reasoning, but with Redux this is taken to extremes: a tiny core library, documentation that's mostly boilerplate, and much greater cognitive overhead than any other state management.
I opened up an issue earlier this year to discuss possible ways to improve the experience for new Redux users, and additional useful abstractions that could be built on top of Redux: https://github.com/reactjs/redux/issues/2295 . If you've got feedback or comments, I'd encourage you to contribute them to that discussion.
Also, as unofficial keeper of the Redux docs, I'd also appreciate any suggestions for improving them. Can you clarify what you mean by "documentation that's mostly boilerplate?
If you're looking for more of an "integrated" Redux experience, you might want to look at https://kea.js.org/ .
I'm actually already using Kea. Thanks for the suggestion, it's an awesome project!
By boilerplate I mean that the docs are written using examples of e.g. a single network request and a handful of actions, where even a small application with a few repeated bits of code would introduce abstractions for common elements. Because the docs lay out the simplest possible way to do this, they don't fully represent a real app, and because the ecosystem is so vast, it's not obvious which abstractions are state-of-the-art.
Filling in the "next steps" tab with some hints about where to go would probably help a lot.
Huh. Indeed, that "Next Steps" page never has been created. That's an excellent suggestion, thank you. I just opened up https://github.com/reactjs/redux/issues/2626 to cover adding that docs page.
If you or anyone else reading would like to contribute writing that page, please leave a comment and let me know!
And yes, it's always tough to balance the various audiences and use cases when writing docs. Minimal examples like a TodoMVC can be helpful for showing off basic concepts and keeping a learner from getting too lost, but then those don't cover the complexities of a real-world app.
Actually have a request for you, now that I think of it. Like most of the addons I've catalogued, I haven't had a chance to play with Kea myself. I'd be curious to hear your thoughts on how useful it is, how it compares to using "plain" Redux, and so on. Please leave a comment here, or catch me on Reactiflux.
Hey, author of Kea here. I'm always very interested in feedback as well! :)
So strken, acemarke and others: Feel free to reply here, contact me on reactiflux (@mariusandra) or shoot me an e-mail if you feel like talking about Kea.
Cheers and thanks for all the nice words so far. :)
I might do a write-up of implementing the same app in Kea and vanilla Redux, and if I do I'll get in touch with you on Reactiflux. Thanks for engaging in such a positive way with the community!
And this attitude is equally frustrating. Tools and libraries exist to save developers time. The cognitive overhead of building and maintaining your own framework piecemeal can be detrimental to shipping code, especially if you don't have pragmatic and decisive leadership on your team.
It shouldn't be. If you don't like a tool, don't use it. Nobody is forcing you to use redux, you don't need it, even if you're building a complex react app, setState works just fine, seriously.
> The cognitive overhead of building and maintaining your own framework piecemeal can be detrimental to shipping code
So don't do that. Identify the problem, then use the tools that solve the problem, if you can't figure out which tool is the right one for the job that's your problem, not the fault of the tool. If I need to drill a hole in my wall I don't complain about how many drills are on the market, I just use the simplest tool to get the job done or hire someone who knows what they're doing
> especially if you don't have pragmatic and decisive leadership on your team.
The tool is not responsible for someone failing to use it correctly, that's absurd.
> Nobody is forcing you to use redux, you don't need it
This is hand-waving to deflect Redux from legit criticisms, and is part of the reason I find both responses frustrating and unnecessarily dismissive.
You need to build your own framework for React SPAs because they're intentionally un-opinionated about the pieces you use. Just look at the scaffolding in place for create react app and all the various libraries. I would much rather solve real problems than discuss how to get Immutable to play nicely with Typescript or argue thinks vs. middleware.
"Get good" is a poor response to anyone wanting to see the wildly used/discussed state management solution for React get better, and implies that there aren't good devs out there with experience outside of JavaScript saying there is a better way.
You're right though - there are choices. I didn't like how the JavaScript ecosystem was progressing so I made a choice to not deal with it anymore professionally and it's been a very rewarding career change.
> This is hand-waving to deflect Redux from legit criticisms
The comment I responded to is complaining that a list of tools makes them feel exhausted, that's not "legit criticism" that's low-effort whining. The legit criticism already received a response in the form of a list of tools meant to obviate the specific issues outlined by the critic, but somehow those tools being available is cynically characterized as a negative thing because some people don't know when or how to use those tools. That's their fault, not the tool's.
> You need to build your own framework for React SPAs because they're intentionally un-opinionated about the pieces you use
This is an engineering trade-off, it's not inherently wrong or bad; it's like whining that you have to spend time learning how and when to use a clutch when operating a manual transmission vehicle when an automatic would just figure it all out for you. Sorry, just because an automatic has a lower learning curve doesn't mean its a superior car, it's just a tradeoff, convenience over control.
> I would much rather solve real problems than discuss how to get Immutable to play nicely with Typescript or argue thinks vs. middleware.
So. Don't. Do. That.
You don't need those things to use React, that's a choice you're making because you apparently desire the features that those tools afford you as a developer, yet you're complaining because you don't like the consequences of the engineering decisions YOU made. I've written and deployed around eight React projects into production and while some of them use immutable.js, none of them use typescript because the team's experience with typescript is limited. You see that? We don't know how to use typescript... so we don't... and everything is fine.
> "Get good" is a poor response to anyone wanting to see the wildly used/discussed state management solution for React get better,
My response is not "get good", my response is quit complaining that tools exist that you don't like. You don't have to use them, especially in the React world where you get to pick and choose the tools that work best for you; if you find the choices overwhelming that's your fault, it's not the tools fault that it exists.
> and implies that there aren't good devs out there with experience outside of JavaScript saying there is a better way.
This is hilariously arrogant. People who don't work with JavaScript want to complain that there is a better way to do work in JavaScript. If there is a better way then put your keyboard where your mouth is and build something better rather than complaining about the existence of tools you don't like.
I’ve spent a few months writing code in a moderately large redux app and hadn’t heard of any of these. Maybe more could be done to call them out in redux docs?
Agreed. I made a comment elsewhere in the thread linking to an issue I filed for revamping the "Ecosystem" page, and asking for help from the community to improve the docs (since my own free time is limited): https://news.ycombinator.com/item?id=15343818 . You may also want to check out my React Boston talk about the Redux ecosystem, also linked upthread: https://news.ycombinator.com/item?id=15342225 .
That's truly hard work to rewrite everything from scratch and keep the legacy API untouched! OOC - what was the most difficult feature/bug to preserve/fix in this process?
It's possible in the future, but re-licensing React itself was already a very large change, and it will take more time to review the possibility of this for other projects like RN. Thanks for your patience!
Yeah, pity said large change was implemented before checking if it was a good idea.
Community: This license is a legal nightmare. Something needs doing!
Facebook: We have done something.
Community: Try listening to both sentences next time.
I'm not in anyway connected with FB, but I think the reason why React was licensed under MIT more quickly than React Native is because of that licensing environment. Web frameworks traditionally have very open licenses, but native seems more more restricted such as with Qt and the C# thing I don't remember the name of.
Except the largest 3rd party Objective-C and Java (Android) libraries are usually MIT as well. I don't really think this has to do with traditions as far as per platform licensing goes.
Everyone can, that's precisely why they gave you a grant previously. Now that it's gone due to the outcry it's in the same, vague playing field that all other libraries are in. Every project you have ever written infringes on someones IP. The only thing that matters is that lawyers that previously got cold feet can now relax. We had a project for instance that was canceled, now it's being green-lit thanks to the MIT license.
Actually, there is an (albeit so far untested) implicit patent grant in all-permissive licenses like the MIT. So removing the explicit one-way, revokable patent grant actually implicitly provides a better patent grant.
This is not untested, only untested in the software field.
It's very very very well tested in other fields.
So far, every court ever (and there are quite a lot of them) has said "when you tell people they can use your thing and do what they want with it, you can't sue them later for infringement for doing what you said was okay".
There is pretty much zero precedent on the other side.
In fact, one of the only related pieces of precedent on the other side, which was "attempting to avoid patent exhaustion by contract" was completely and totally overruled by the supreme court last year, where they unequivocably said that sales exhaust patents, no matter what you make a person agree to.
Black and white is not as good as everyone seems to think.
There are reasons you don't enumerate every possibility ;)
(courts will then interpret that as a complete list, instead of extending it to cover similar situations)
If you had black and white fair use, for example, you'd just be railing against the fact that courts wouldn't extend it to cover new similar thing X.
Black and white is good for establishing baselines in law (IE "these things over here are definitely okay, and everything else should be judged by these factors"
It's rarely that great if you are trying to make a license that stands the test of time and march of technology.
The fact that MIT and BSD licensed code (implicit patent impunity) can be re-licensed under the Apache license (explicit patent impunity) is enough evidence for me.
I don't know. But Facebook owns around 5200 patents. Add the previous patent clause to it and you have a good probability that there are patents covering parts of react. VirtualDOM is certainly a candidate.
Here's the problem with that type of snark; when you're wrong it's really bad for you. You are responding to a question about react NATIVE, which still has the patent grenade (see below).
Not sure, but that's not relevant to the patent grenade. It revokes your license if you're involved in ANY patent action against Facebook, regardless of that patent being used in RN or not.
However React == React Native evals as true due to type conversion (in ECMAScript projects with or without a patent grant are both considered 'truthy'). Really even === is not good enough, The only reliably why to test for it right now is to put a patent claim against FB inside a try-catch.
* I am not a lawyer and this should not be taken as legal advice.
That blog post mentions your featureFlag approach, the initial dogfooding and then the gradual rollout. I'd be very interested to hear on top of that:
1. How did you approach the rewrite on the coding side? What I mean is: Did you just say "Okay, let's start from scratch and use the lessons learned from v1?" Or did you use a specific approach along along the lines of: "Let's structure our code based on these principles and ...?"
2. When you started the rewrite, how did you know in advance and make sure that the rewrite would be faster and have a smaller code-size?
3. Was your focus during the rewrite on a cleaner code base (and the performance improvements followed automatically) or was your focus on speed right from the start?
4. Any other lessons learned during the rewrite? Patterns and approaches that helped/didn't help during the coding?
The conventional wisdom in software development is to never rewrite your application from scratch. Typically it's much more difficult than you thought it would be, and it takes too long. Meanwhile, competitors pass you by (remember Netscape?). Just wondering how you came to make the decision to do this, and what, if any, concerns came up along the way?
I always remember how the SQLite author Richard Hipp talked about being able to rewrite major chunks of the SQLite engine due to their test coverage. Their testing page currently says they have 730x more test code than core library code. https://www.sqlite.org/testing.html
The conventional wisdom applies to large, complicated software. The source for React comes in at around 109kb now. That couldn't be more than 10-20 thousand lines of code, which is quite small.
We used it because it produces a single flat bundle without extra module boundaries. I think webpack 3 might do the same with the experimental concatenation plugin, but we're fairly happy with Rollup.
The "react" package is mostly irrelevant here since it only contains a few utilities. The actual reconciler is synced separately, and no, it isn't enabled in RN yet (but maybe will be in the next stable release).
Lovely. The file size reductions are quite surprising.
Removing the need to wrap sibling elements in a single parent element is a welcome change.
I'd be interested in hearing some use cases for using the Portal API.
Lastly, the new licensing announced last week was fantastic news. I commented on last weeks thread, but I want to extend another round of compliments to Facebook and the React community as a whole for prompting this change. Props to them.
We use portals quite a bit in our application and they always are a pain to test. This is what excites me the most about React supporting them natively. Hopefully this means that enzymejs will be able to easily walk down and seamlessly jump into a different part of the DOM without having to use references to adjust.
Portals are helpful when using content overflow in modals. For example, we have a modal which contains a form and that form has an autocomplete text box. When we render the autocomplete part, we need to render it outside of the modal, otherwise the overflow policy blocks the contents and does not allow the autocomplete are to appear over / outside of the modal.
The use of portals also make it easier to support screen readers through the aria tags by allowing the application to quickly block the background of the application and allow the screen reader to focus on the content presented to the user.
This does worry me a bit though. There is probably a reason they are difficult to test, because they go against the React DOM pattern of a component only having control over the DOM nodes inside it. Call me a purist but this seems like a deviation from React's functional roots and going against the very problem React was trying to solve in the first place.
The portal API sounds great for modals and dropdowns. It looks like a good fit for react-float-anchor[0] (used by the more interesting to look at react-menu-list[1]). I'm currently abusing `componentWillReceiveProps` to get portal-like behavior, but it means that test code has to do react-float-anchor -specific things in certain situations to see elements rendered in it.
Both of the CodePen example links on that page are insidiously broken. The demos appear to work, but they don't actually demonstrate the claimed portal functionality at all:
// These two containers are siblings in the DOM
const appContainer = document.getElementById('app-container');
const modalContainer = document.getElementById('app-container');
Note that both variables refer to the same element.
No problem! And on re-reading my comment, I probably shouldn't have used the word "insidiously", it came off a lot more negative than I intended. Thanks for the quick fix.
I've used portals to make modals, as they often have to be close to the root. This has had many quirks and bugs from code not expecting to be in a portal, hopefully it being a supported concept fixes this.
I'm impressed by how accessible Facebook makes open source tech. It's always top notch but documented in a way that allows regular devs the opportunity to use it in their own apps.
Smaller size and easier to use is a big win. Going with the MIT license puts a real bow on this release. Thank you to the React team.
Ditto. And this new release seems to have been characteristically well-handled. I love http://isfiberreadyyet.com, the engineering team's blog, their responses to github issues etc.
My level of genuine respect for the way they do open source makes me feel a bit awkward about the fact that I dislike FB's primary product and mission. Especially given I make quite a bit of use of their code.
Seriously! Great news. My company is not just a software company, so when I proposed using React before (under the BSD+Patents license) it would have killed our ability to enforce our non-software related patents against fb.
Assuming you're referring to the licensing part, it's probably because they've gotten a lot of public backlash for their previous licensing scheme that has caused some to avoid React altogether.
Great release but forcing the capturing of errors seems to violate the JS value of forgiveness. Worse, this "forcing" actually seems to hinder debugging.
For example, I have one component that throws an exception. Previously, React would print the stack trace in console and carry on. Now, it destroys the entire DOM, spews three times as many errors, without even letting me see what the visual result was of that error.
To debug, I need to write a componentDidCatch method in the parent class of the erroring class, because the root componentDidCatch error handler can't reconstruct the DOM, because of that one sub-sub-sub-sub-sub-child state error.
Even after writing all this new code, React still removes the erroring element from the DOM, leaving ambiguous what its impact was on the end-user experience.
Does anyone else feel that the new version of React is fault-intolerant?
While I do enjoy Java, I would argue that Null-Pointer-Exception hell does not belong in JS scripting.
No, that's the opposite in my opinion. You should be catching errors. Ideally as early as possible. Most ideally when compiling your app, least ideally on a user's computer. I think a previous article on HN elegantly put it as, "move errors to the left."
While this is more of a lateral move, it's an important one. Before, an error during render left your app in an undefined, potentially unstable state. Then, you might find some unrelated junk errors in your Sentry or whatever you use, and on top of that the user is wondering why when they click nothing happens.
Now, you can recover from an error completely, even if you don't have control over the code running in other components. That's a big deal when you might want to have third party components or something to that effect.
Can you please file an issue? We can discuss specific pain points and concerns there.
It's a bit hard to reply to a comment here with technical points :-) The valuable discussion will get buried.
As explained in the blog post about error handling, the recommendation is to add error boundaries in "strategic places" (e.g. around main UI blocks) so that they fail gracefully. But it requires some design input on how it should work. It means error states should be part of your app's design, and I understand this might seem unusual.
Still, let's please continue this in the issue tracker.
Everyone with a legacy codebase will probably update their components to extend a common class that handles errors in some very generic way without propagating them up the tree.
I'm not sure how I feel about this change, but at least there's an escape hatch.
Yes yes, this is incredibly impressive. Very smart as well for ease of getting people to adopt the new version. I was fearing that I'd have to redo who knows how much just to use 16.
2 awesome things about this release:
1) No need to wrap siblings in an enclosing element - upgrade is worth it just for this change alone (j/k)
2) I'm surprised no one has mentioned it so far -- but this release uses the new fiber architecture - I saw the video presentation about fiber and think it could really help in terms of performance
Portals seem like a great idea. It seems like it eliminates one of the major use cases (imo) for inlined styles: rendering child components deep within the DOM when visually the component doesn't appear that it should be that deep (e.g., rendering a global level modal that in the DOM might be appear in a deeply nested div). That always wreaked havoc with stylesheet selectors and is one of the reasons I started moving towards injected inline styles.
Overall reduction of container elements is a huge plus. I'll be happy if I can start thinning out the giant christmas tree that react tends to create, even if it's not a huge performance gain, this will improve debugging immensely.
So, what's the current ES5, non-Babel/Webpack/Rollup/Brunch/etc story of React? When I first tested it, all you had to include was two Javascript files and you could go, and if you were foregoing JSX it was even easier.
These days it seems you need to download half the internet for even the most trivial uses, never mind using the half-finished ersatz JS du jour. And yes, I know that it gets compiled to a tiny thing worth of the IOCCC for the end user, but sometimes even us programmers want an easy setup.
It seems the only framework that still has a good story regarding that is Mithril…
Looks like Mithril code (https://mithril.js.org/) if you alias React.createElement to a short function name.
I learned Mithril before React, and kinda think it's a better learning experience to learn the simple way like this first, and then add build tools, Redux, JSX later (if you choose to).
So much good stuff in here. Perf wins, in both bytes down the wire and render time. I've been wanting to return sibling elements from render for years!
Crazy to see such a robust, mature framework still improving so much. Can't wait to upgrade!
Really excited about Portals. I work on a web app which was originally built with Spine.js (an MVC framework similar to Backbone). We've long moved on to React and Redux but have a few old views that have yet to be ported over. Portals seems like a nice way to refactor by incrementally replacing controller + template logic with components.
I'm also glad to see the switch to MIT license if only to put this patents controversy behind us. Now curious to see what happens with GraphQL...
Yeay! GraphQL specification has been relicensed minutes ago to Open Web Foundation Agreement, graphql-js and relay to MIT. Great stuff from Facebook today.
Portals are like one of those ideas (like all great ideas) that are incredibly useful but seem obvious in retrospect. Thank you facebook and the react team for all your hard work!
Because now it's exactly like every other piece of open source software, so lawyers can stop debating whether it's better or worse than an implicit grant.
I had a serious cringe reaction to seeing that term. I hope that the web 1.0 portal concept is sufficiently dead and buried that we can now rebrand "portal" to something useful.
I'm super excited for pseudo-components. This should make it much easier to use CSS constructs like flexbox and the new grid system since they don't like nested DOM tags.
I tried to make a set of React components that worked like a table (with rows and columns) using CSS grid in React 15, but it was nearly impossible to do. For the record, the reason I didn't just use a table was because the grid system allows for more expressive sizing of columns than plain tables.
The big news it that they removed the PATENTS.md file that made it nearly impossible to use for anyone concerned with protecting their IP. Good on them for making right with the open source community.
i wonder: if you don't have a contractual relationship preventing it, can't fb revoke your permission to use their patents at-will? if so, has removing the patent grant actually changed anything?
It's actually the other way around, as I understand it. This is one area in which patent law and copyright law differ noticeably.
Due to the way implied patent licenses work, if Facebook distributes React without explicit restrictions or conditions, they're automatically granting a license to any patents that are inherently infringed by React itself. This is a pretty well-established area of US patent law, see e.g. https://www.wilmerhale.com/pages/publicationsandnewsdetail.a...
Thank you FB React team. Along with the new license I can't be happier to see your good work and improvements on React.
Before the license change I was looking around for other options, but now I can continue to enjoy front-end development with this awesome library for at least a few years more. For me this definitely helps fighting JS fatigue not having to change to another framework.
Small nitpick: the reduced file size appears to be, in part, due to depending on Map and Set. Polyfilling these will, in turn, increase file size so there's no real file size impact in practice. IMO the blog post could've been more honest about that.
This wasn't actually the reason for the reduction, but it is something we weren't acutely accounting for since we already have Map+Set polyfills in our apps and expect most other users to as well. We'll see if we can recommend a smaller polyfill that isn't as large.
Awesome! I must admit I never really saw the added value of Map and Set given the size increase - for most purposes objects and arrays work fine in practice.
The polyfilling is only necessary for IE10 and lower. Many people who are conscious about size don't support old browsers so that's a real win for them.
You could also include polyfills conditionally by sniffing the user agent.
I'm also fairly sure there exist smaller polyfills for Map and Set. We should probably look for them and suggest them instead.
Per Dan's suggestion, you should start with the actual docs.
After that, I keep a big list of links to high-quality tutorials and articles on React, Redux, and related topics, at https://github.com/markerikson/react-redux-links . Specifically intended to be a great starting point for anyone trying to learn the ecosystem, as well as a solid source of good info on more advanced topics. It includes links for learning core Javascript (ES5), modern Javascript (ES6+), React, Redux, and much more. I also published an "Intro to React (and Redux)" presentation at http://blog.isquaredsoftware.com/2017/02/presentation-react-... , which is a good overview of the basic concepts for both React and Redux.
Also, the Reactiflux chat channels on Discord are a great place to hang out, ask questions, and learn. The invite link is at https://www.reactiflux.com .
Thanks! In the past I've looked at the docs and got something basic going with create-react-app, but since I've been put off by little things here and there I'd like to see a working example of a larger system to better appreciate what's good about React. This seems like what I was looking for.
Those are both pretty broad questions. Skimming through the code, I'd say it's a reasonable example of a React+Redux codebase. I don't think I could say it "leverages React to the fullest", because it's unclear exactly what that means, and this is not an overly complex sample application. But, it does serve as a useful example of something more "real" than yet another TodoMVC clone.
Congrats for shipping this for everybody involved! 16 has been a long time coming and I super happy for all the new features it brings us. Error boundaries! Fragments! Even better SSR! And so much more.
If I'm building a site where SEO is paramount, am I safe using React and SSR? I'd kinda like to, but my inclination is to stick with a traditional server page approach.
SEO-wise there's no difference other than performance. But it was possible to build high-performance SSR sites with React 15, and with React 16 it's even easier.
The more important thing to decide is whether the development model of React is suitable for your needs.
We're actually doing this right now with tylio.com. We get pretty high scores (95+) on the various test tools (Pagespeed, Lighthouse, etc.) using React 15. Our biggest remaining issues right now are First Meaningful Paint and Time to Interactive, and I expect React 16 to help a lot in that aspect (streaming render + simplified rehydrate), can't wait to test it!
Because it is hard to know the implementation details of every search engine and what reasons different markup could result in a subtle difference in ranking, I think the best way of answering this question is looking at the markup differences between HTML produced via ReactDOM.renderToString() vs. some other solution. In versions of React prior to 16, some extra attributes were added to the markup, but besides that it looked basically identical to what you'd get using any other method. Now there is even less difference, so it's hard to imagine React SSR having significantly different SEO characteristics.
But one caveat is that if you need to hydrate serverside-rendered React markup for clientside use, that will add at least some small performance penalty. And you will also want to pass in props data that matches as closely as possible between the client and server, which means that your base page will need to include some serialized version of the data that should be passed in as props to the component(s) you serverside-rendered and want to hydrate. If this is a large chunk of data, there could be negative SEO impact if it is placed above meaningful content in the page or if the time to download it delays complete load of the page.
Definitely. As said below, SSR is definitely the way to go if you care about SEO. Although Google claims to be able to handle client-side rendered web pages, it won't work as flawlessly.
I work on Asia's largest real-estate portals and we use React 16 and SSR. If you want to talk more about what we've done, contact me: swen [at] sectorlabs.ro
I think you can (with a warning), but it's still recommended to use the normal React naming conventions according to [0]:
> Note: always use the canonical React naming for all supported attributes.
Looking through the examples, it looks like non-string class values will be converted to strings, while non-string className values will be ignored (with a warning).
Just for clarification, React 16 does not support streaming, at least not in any way that is meaningful. React 16 has an API that gives you a Readable stream, but this stream doesn't provide HTML in chunks. It provides it all-at-once exactly like renderToString does.
What you really want with streaming is whenever rendering is blocked by something asynchronous, like a database request, that whatever HTML is finished can be flushed out. React could support real streaming in the future, but would likely require some new API.
Anyways, the sentence from the article "start sending bytes to the client faster" isn't factually true, it doesn't send it out any faster than renderToString would.
You don't need to wait for the CPU time of all components to complete before the first bytes are available. When we render an HTML element, we now emit the opening tag before processing the children. People have seen benefits in practice from this.
Our new architecture makes it easier to implement the type of async data fetching you describe and we'd like to add it in the future.
Depends on your criteria. At this time I feel like React has a larger ecosystem (assuming there isn't a lot of incompatibilities with v16), and there's a clear path to mobile if that's a choice. Vue seems to be a simpler programming model, and makes it easier to iteratively build. Personally I'd say don't make a choice at the beginning, but build a simple version of your app in both (say login and 2 or 3 pages) and make a decision based on that.
Vue is less complex, easy api, and easier to jump into. React is more complex, bigger learning curve, but more featured. Vue has satisfied my needs for 99% of projects.
This really boggles my mind. Having looked very closely at both (and being a react developer full time), I can not recognise this assessment. I just can't see how people can claim that Vue is simpler or easier than React.
React is idiomatic javascript. Vue is it's own quirky thing that doesn't feel anything at all like Javascript to me.
Different peoples brains work differently. React clicks with your brain, but not Vue. I've been doing web development since 1996. I read through both the React documentation and the Vue documentation. Vue just clicked with my brain. I totally groked it from the beginning. React... not so much. Vue has been amazing for us so far.
I'm not sure what feeling anything like JavaScript has to do with the discussion. No one asked which framework is most like JavaScript. I don't think JSX turning JavaScript into some weird XML/HTML hybrid feels like JavaScript either. Sure you can use it without it, but why would you? Vue works for me and others, whereas React works for you, and others. Let's just keep working on our projects.
I'm talking about switching between a context where there are first class functions that can be easily passed around, to a context where there's some archaic and magical, non idiomatic convention based on string based dependency injection, or magical way of writing attributes.
Depends what you call idiomatic. I dont think JSX is really a JavaScript idiom, more like a HTML idiom applied to JavaScript which happen to be often used together.*
At the end of the day, I think that calling something idiomatic is subjective and so, varies from people to people.
*: to be clear, my point is many people use JSX with React because it feels idiomatic (I manipulate HTML/DOM, so why not just write with HTML-like syntax?) but it is not idiomatic to JavaScript and I don't think the other React APIs are that nice to use. If I didn't use JSX with React, I'd tend to use other framework because, in my opinion, they make more sense.
Think I see what you are getting at--in practice most folks using React are going to use JSX and build tools, and if you alias the function it's kind of non-standard.
Mithril has "class" instead of "className"; that irks me too.
And vue optionally supports Jsx, so original comment or using it as a reason why ‘react sucks’ is being super pandentic. It’s ok to have multiple frameworks!
Whether Vue or React is a more "complex" I think depends on how in depth you want to understand it. I could see that Vue is less complex to use, at least superficially, but I think it's way harder to understand.
When I look at the guide and I see stuff like this:
<div id="app-2">
<span v-bind:title="message">
Hover your mouse over me for a few seconds
to see my dynamically bound title!
</span>
</div>
I get immediately queasy about what Vue is doing. Does it parse the HTML? How exactly does scoping work? What sort of special classes and expressions can I put in the span, and in what manner will they be evaluated?
In contrast, React is a JS library, and works like any other. JSX is weird for the first minute, but it's a very light transformation to the underlying JS, to the point where when I write it I can mentally see what JS functions I'm invoking, which therefore helps me understand all those things I mentioned before like scoping rules, what this will refer to, etc.
This has been my experience as well. With react if I need something I can generally find a component someone else has already made that is well supported / decent quality. With Vue I will generally have to roll my own.
I am referencing "component" as a more general term. I think Vue has support for all of the common forms/divs/etc, I was more talking about like if you wanted an extensible calendar implementation or a scalable data table implementation there are probably 10 usable components for each of these examples in React but in Vue it would be harder to find one.
Vue is as easy to learn as Angular was. Saying that Vue is less complex - this line gets thrown around as if anyone would easily agree. It is a traditional templating framework, it ships its own javascript emulator and scripting engine, you re-learn everything. Composition is not natural to it. Every single structure is arbitrary. It has an API documentation that spans 70 pages. The cognitive overhead is large.
If you know plain javascript you know half of what makes react. The API surface usually consists of a single function: render. The rest are 3-4 class lifecycles, setState, a few jsx semantics and that's it. You solve problems in the same way you always solved them, there is nothing to re-learn and you don't bend to the framework.
Go ahead and re-create this in Vue, tell me what you're doing is easier:
A beginner could blink at this once and start making simple apps blindfolded. A Vue beginner would be stuck even trying to create components, not to mention compose them, or pass props, or access the import. Every single step on top of this has to be fished out of the documentation: children, conditions, loops, filters, etc.
Oh please. React itself might not be that difficult but thrown in couple overly engineered libraries like react-router and immutable.js and that poor beginner will start feeling a bulging Javascript fatigue in their foreheads.
Once you get rolling both of them are good but it's no easy task to start-up a React project on your own. You need a lot libraries, have to twiddle with immutability which is no piece of cake with JS and be constantly aware of small quirks like keys when looping jsx-elements, className instead of class, how to add css preprocessor, using setState instead of directly assigning to it with the constant farce with deeply nested Object.assigning oh such fun.
React tries to make the world a better place with more theoretical approach while Vue focuses on tried-and-true methods that work and are straight-forward for everyone with a little experience in programming. (v-if might not be pretty but it beats JSX conditional) Granted modern frontend development has a lot of different things to be aware of that make it bit difficult for beginners but IMO Vue makes it a lot more simpler and productive. Some things I wish might be better like the ecosystem but oh well. Overall I'm happier and the only problem is having to fight off overly smug React-developers who have rubbed their egos so hard that they aren't able to even think about better solutions anymore.
immutable.js for what? Seems to me you're picking up hear-say here and there but why and for what would you want to use immutable. Even redux docs speak out against it. It's just a random tool like any other, you're assuming it has some deeper significance with react, it doesn't.
> be constantly aware of small quirks like keys when looping
There are no "quirks" in looping anything. It is plain javascript. I would call "v-for" a quirk on the other hand.
const array = []
for (let item of items)
array.push(<li>{item.text}</li>)
render (
<ul>
{array}
</ul>
)
I only wanted to show that react doesn't specify a programming style. He said javascript maps are "quirky." Maps are fine but so are plain loops. Ternaries are fine, so are plain if-then-else constructs if someone would like it better that way.
The example would run without keys, it's merely for demonstration. You'd need keys in Vue as well.
Vue supports JSX just fine. It also simplifies many things when compared to React:
• lifecycle method names: mounted vs componentDidMount
• proptypes: builtin vs `import PropTypes from 'prop-types'`
• component creation: basic JS object vs ES6 class extending `React.component`
Please don't spread misinformation because you prefer one way of writing frontend apps to another. React is better at complex apps, and Vue has a simpler API that many find easier to memorize.
It's rude to insult other commenters by saying "A beginner could blink at this once and start making simple apps blindfolded." I think you're being hyperbolic, but it comes off as condescending.
Frontend is hard. No one "blinks at this once" and learns how to build component-based layouts with view, data, and logic. Please be nice.
Why don't you actually recreate the snippet of code up there. The same arguments won't win you a price, and i don't agree with them for all the reasons i've stated. Show me how Vue handles the situation up there in such an easy way please, then we would have something to discuss.
> Frontend is hard. No one "blinks at this once" and learns how to build component-based layouts with view, data, and logic. Please be nice.
You seem to purposely misunderstand me. I never said someone could learn react by looking at it. I said someone could understand the nature of simple composition by looking at it.
I learned Vue fully in maybe a few weeks. React in an hour here: egghead.io/courses/react-fundamentals If you think that studying a 70 page document in order to carry out basics like composition is easy then so be it. If you'd actually dare to post the example in Vue, we'd all see how "easy" the hoops would be you'd have to jump through to realize it.
The above could be expressed more succinctly in JSX (I just can't be bothered reading up on the syntax since, as mentioned, I've never written anything in it and consequently don't know it). More info on Vue's JSX support here: https://vuejs.org/v2/guide/render-function.html#JSX
Why are you being so confrontational? Seriously. We're discussing web frameworks. This isn't needed on HN, or anywhere. I come here to avoid all the negativity on the web. You enjoy React, we get it. Relax.
Good call. Although the timestamp would have been impossible in Vue since templates don't have scope, they couldn't access imports. One would have to jump through another hoop and inject/duplicate the function into a template method.
"A beginner could blink at this once and start making simple apps blindfolded." Um... I've been doing web development for decades and I don't have a clue what those lines of code are doing.
Other than the es6 syntax, would you like to specify what it is that you don't understand? If you look at it, it must occur to you that react components are functions that can receive properties and return markup. Now you can compose these functions. Just like in Vue or any other framework there is a single mounting point. If you understand this, you know the largest part of the react library.
I never said you know react by looking at it. But you know it good enough to build a simple composition. If i asked you to create another component up there that contains a span, are you seriously saying you wouldn't be able to do it after having looked at it?
const Foo = () => <span>hey</span>
or, same thing in es5
function Foo() {
return <span>hey</span>
}
?
And if i asked you to use this component in another, even if you saw how it's done, you would absolutely not be able to pull it off again?
function Bar() {
return <Foo />
}
?
To be honest, i thought i didn't like react as well when i first encountered it. I didn't actually try to understand, the appearance of it seemed so radically different that i refused to think of it as simple. But i eventually tried and figured that there is actually nothing behind this framework. These are plain functions, or classes with lifecycles. I was wrong in my assumptions.
I think this is a misleading answer. It only appears that way because the React ecosystem is much bigger and tailored to more complex applications. Comparing the Vue library to the React library I find it hard to recommend one over the other -- at the end of the day they're pretty similar.
Sincerely, we should be leveraging the browser platform and increasingly build our apps on modern platform APIs (e.g. web components), instead of on a framework platform that means more bytes down the wire to do what the browser platform can already natively do.
Admittedly there are tooling gaps with projects like Polymer, but these are being addressed. YouTube.com is already in production built with Polymer.
So just leaving this comment here to encourage everyone to rethink the framework defaults of React/Vue in 2017.
Video here from Polymer Summit on the genesis of web components and the problem it was meant to solve (explosion of frameworks circa 2010, and slow JS apps): https://www.youtube.com/watch?v=y-8Lmg5Gobw
It's actually a very legitimate answer. Vue and React are similar tools that solve basically the same use cases, with some technical and cultural differences.
- React uses JSX and JS logic for render methods. Vue usually uses templates, although JSX is also supported.
- While React _can_ be used as a plain script tag, it's usually compiled as part of a build step. Vue can be compiled, but it seems friendlier to the "drop-in script tag" approach.
- The Vue community values official integrated addons for routing and state management. The React community prefers a "pick-and-choose your own adventure" approach.
- Since React has been around longer, there's probably more React components and related libraries available
- A larger percentage of the Vue community is located in China
The best comparison of Angular, React, and Vue I've seen thus far is at https://medium.com/unicorn-supplies/angular-vs-react-vs-vue-... . It lays out a lot of the similarities and differences in a fair way, and gives some suggestions for why you might pick one over the others.
Sure. I am well aware of these differences. They are basically two different implementations of the same idea with two communities that do things slightly differently.
What I fail to see is how I would choose one over the other for different types of projects. To me, it's a choice a person or a team makes for all projects at once. Jumping back and forth between stacks here would be a lot like jumping back and forth between Django and Ruby on Rails. They aim to solve the same thing, and if you can use one effectively then why would you reach for the other?
I think you're overcomplicating how transferrable framework knowledge is. An expert React developer could switch to Vue no problem if there was demand for it. Similarly an expert Vue developer could switch to React no problem.
I am not. The original question was about starting a new project and the orinal answer was “depends on the project”. I am asking how it depends “on the project” and not on the person. What properties of the project would drive you to choose one over the other?
Wire size. Your projects specific needs. Built out time (i.e making your own components). DOM requirements. Licensing. Community. etc. This is an enormous list of variables to determine. If you were not making a complex site or SPA, learning and using React could be huge overkill even though it could still get the job done. The best way to determine what framework or language to use, for me has always been to assemble my tree of needs first. That included things like, how complex are we talking here. Do we need state management? Do we do most of our rendering server side? Do I have to learn the framework? Are the docs good? Etc. Build a map of our own needs first, then spend a few hrs holding it up to the various options.
Still. It's like saying that you need to own both a DEWALT and a Bostitch drill because they are just different enough when working on dry wall in colonials vs capes. I mean I am sure there is someone out there that uses Vue for odd projects and React for even ones (and Angular for every 13th one that they start on a date that ends in a 5), but most developers I know try both, then stick to the one that they like best.
Which appeals to your aesthetic more? If you're looking to grow a team, which is more appealing to engineers available? Which has a better ecosystem of support libraries?
I hate that facebook has basically made a new version of javascript.
I don't like facebook as a company and prefer software that is made by people who aren't told "go make this" by their boss.
Facebook has thrown out all of the previous approaches and just started again. This is good for things like the virtual dom, as the alternatives never worked to begin with, but bad for things like html templates, which have worked fine.
The problem with combining javascript and html (JSX) is that the javascript gets in the way and you can't really see what the component looks.
Vue.js is more of a DSL. React is just Javascript. I'd say they're two very different approaches.
I'd recommend react over Vue any day of the week, to answer ops question. Vue.js is everything I hated about Angular. String based dependency injection, bizzare attibute syntax, highly opinionated.
React is everything I love about javascript. Functional, fast, and with an easy to reason about API.
Counterpoint: React is no less opinionated, fast, or has less of a DSL than Vue.
Opinionated: React is a library written for a language that is not JavaScript (the first prototype was written in OCaml). It demands immutability, which JS has no native support for. it wants you to use FP, but JS natively has little support for FP both in its standard library and syntax. FP only looks good in JS if you've never used a real FP language.
DSL: JSX is a DSL - I can't remember the last time I've seen someone use && as a poor man's if statement, or ternary statements dozens of lines long until I started writing JSX. JSX is neither idiomatic JavaScript nor HTML.
Fast: Performance benchmarks (which admitted are flawed as they can't capture real-world usage) show that React and Vue have similar rendering speeds. Vue's computed property dependency tracing means that a lot of the performance optimizations which require manual work to enable in React (manually memoize expensive computation, shouldComponentUpdate, PureComponent etc.) are handled automatically by the framework.
> DSL: JSX is a DSL - I can't remember the last time I've seen someone use && as a poor man's if statement, or ternary statements dozens of lines long until I started writing JSX. JSX is neither idiomatic JavaScript nor HTML.
Nothing in React forces you in any way to use ternaries. You can do all your pre-calculation in the render method, and if that's your style you would most certainly do that.
const Say = ({ reverse, text }) => {
if (reverse)
text = text.split('').reverse().join('')
return <div>{text}</div>
}
<Say reverse text="hello" />
Btw, Vue isn't any different here, you use ternaries there as well, only that it's severely limited as you couldn't refer to other components, the template is a dead string after all:
template: `
<li v-for="(item, index) in items">
{{ index > 2 ? item : item.split('').reverse().join('') }}
</li>`
> It demands immutability, which JS has no native support for.
It doesn't do that at all. Even redux uses plain shallow copies. Vue on the other hand does exactly that, it uses observables which aren't supported in most browsers. Reason why as of version 3 you will maintain two codebases (one for IE11 and prior, one for evergreen) since Proxies aren't back-compatible.
> it demands immutability, which JS has no native support for.
You don't need native support, just don't mutate state when calling setState, which is a pretty simple rule to follow.
> it wants you to use FP,
This isn't really true. React components are often written as ES6 classes and stateless functional components are only functional insomuch as they are literally just a function. I can't think of any advanced FP concepts that are necessary for idiomatic React.
> JSX is a DSL
Technically true, but in practice it is just ES6 and the HTML side of JSX so closely resembles actual HTML that the DSL criticism loses most of its meaning.
> I've seen someone use && as a poor man's if statement
It may be a code smell, but it's certainly valid JavaScript and not a technique that could be correctly described as contributing to the idea that JSX is a "DSL". Also, you don't have to do that, just use an if statement or a ternary operation to compute your result outside of the JSX block and reference the resulting variable in the template part of the render function.
> React is a library written for a language that is not JavaScript (the first prototype was written in OCaml)
This is incorrect. React was written first in JavaScript in the Facebook Ads org, to be used in the Ads Create Flow application. Jordan's dive into OCaml came later, which is why we now have Reason many years later.
On JSX... ok, that's not Javascript. Nor is it HTML. But it absolutely the right tool for the job, if that job is creating component based web applications.
JSX is such a perfect fit that I take umbrage with people who sneer at it. What better way is there to bridge the gap between the DOM and Javascript? And JSX isn't exclusive to React anymore. That's testament to how useful and practical JSX is. I can see JSX becoming bona fide standard like HTML.
It's not as opinioned as you think. All of the reasons you listed for disliking are just one way of writing it in vue. If you love jsx and pure javascript you can use them as well.
I learned react before vue and found it great compared to angular but lately I've been using vue. It is quickier and neater with the bizzare syntax and lighter overall.
With the latest release I have the urge to go back.
They're both opinionated. Actually, every framework out there is trying to reinvent the wheel (shame on Web Component slow and still ineffective development, what a pity).
I guess will stand out and prosper the one with the largest adoption (to this point, React). All this looks exactly like the old jQuery vs Mootools vs Prototype debate 10 years ago.
JSX is neither HTML nor a template DSL, it simply transform into a function signature. 9 out of 10 frameworks base on the functional approach today, including Vue.
The opposite of an opinionated framework is an opinionated user-base.
You ask what should I use for X (routing, state management, HTTP requests, etc, etc) and every react developer gives you a different combination of answers, and you have no good way to figure out which combination is the best.
I much rather the framework answer those questions for me so I can focus on getting shit done and actually building the thing I want to build.
Your last four submissions are either about eBay (creators of Marko), or a creation of Patrick Steele-Idem (one of the maintainers of Marko). So... you tell us?
Very impressive improvement for a drop-in upgrade! Especially considering the previous version was not considered slow at all given the complexity.