React 16
facebook.github.io
facebook.github.io
Very impressive improvement for a drop-in upgrade! Especially considering the previous version was not considered slow at all given the complexity.
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!
(the 40kb are with core-js, will need to look for something smaller)
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.
Also on being able to use new syntax: https://philipwalton.com/articles/deploying-es2015-code-in-p...
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...
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-... .
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.
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.
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 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
It's a hard ecosystem to bootstrap yourself into.
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.
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.
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 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.
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/ .
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.
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.
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. :)
And you're welcome! I probably spend a bit too much more time answering questions than I really should, but hopefully it's helpful :)
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:
const handleChange = (values) => {
dispatch({
type: PLAIN_MERGE,
state: {
scatterPlots: {
plotSettings: {
[selectedPlot]: {
[axis]:
clipValues: {
lowerBound: values[0],
upperBound: values[1],
},
},
},
},
},
},
});
};
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?
[0] https://gist.github.com/JobLeonard/c4292594ce4d439ab20ec109f...
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.
[0] https://medium.com/@jeswin/implementing-redux-is-tedious-but...
[1] https://medium.com/@benevolentNinja/minimal-redux-setup-e6a1...
[2] https://github.com/reactjs/redux/issues/155#issuecomment-113...
[3] https://github.com/reactjs/redux/pull/140#issuecomment-11395...
[4] http://redux.js.org/docs/recipes/StructuringReducers.html
[5] http://redux.js.org/docs/recipes/reducers/NormalizingStateSh...
[6] http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao... , http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao...
> 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.
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?
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].
[0] http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao... , http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao...
[1] https://github.com/markerikson/redux-ecosystem-links/blob/ma...
[2] https://github.com/markerikson/project-minimek
[3] https://github.com/markerikson/react-redux-links/blob/master...
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.
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.
[0] https://medium.com/swlh/the-case-for-flux-379b7d1982c6
[1] http://redux.js.org/docs/faq/General.html#general-when-to-us...
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 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... .
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.
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.
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?
If there is one, I'd like to hear about it.
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.
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.
...but please read this really quite old article if you haven't before: http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/
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.
/shrug
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.
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.
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.
https://github.com/tjdavies/copal
Its basically the same as Redux in intent but nicer to work with. It even supports the redux dev tools
I'd love to hear contrary experience.
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.
This.
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.
Quick note, you can accomplish this directly using the "context" feature of React, which is what Redux uses under the hood anyway.
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].
[0] https://medium.com/@mweststrate/how-to-safely-use-react-cont...
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.
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.
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'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 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.
[1] www.barvas.com
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.
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.
I've definitely noted that React devs seem to fall into either a "component-centric" view of the world, or an "app-centric" view. Both are okay.
I'll also point out that the Redux FAQ explicitly says it's up to you as a developer to decide what state should live in Redux, and what is better suited for local component state: http://redux.js.org/docs/faq/OrganizingState.html#organizing... .
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.
Which design decisions are you thinking of?
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].
[1] https://guide.elm-lang.org/interop/javascript.html [2] https://stackoverflow.com/a/14604042 [3] http://www.cs.cornell.edu/courses/cs312/2004fa/lectures/lect...
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.
[0] http://blog.isquaredsoftware.com/2017/03/declarative-earth-p...
[1] https://speakerdeck.com/shortdiv/supercharge-your-maps
[2] https://github.com/markerikson/react-redux-links/blob/master...
https://github.com/erikras/ducks-modular-redux
I'll also point out that those tools are all listed in my Redux Addons catalog at https://github.com/markerikson/redux-ecosystem-links , albeit nested inside the different category pages, and I did just highlight them all in my ReactBoston talk over the weekend (slides and video at http://blog.isquaredsoftware.com/2017/09/presentation-might-... ).
Happy to answer questions if y'all have any. :)
https://medium.com/@leeb/relicensing-the-graphql-specificati...
* I am not a lawyer and this should not be taken as legal advice.
https://github.com/facebook/react-native/blob/master/PATENTS
Community: This license is a legal nightmare. Something needs doing! Facebook: We have done something. Community: Try listening to both sentences next time.
Can you clarify your concerns?
Ultimately the React ecosystem would benefit from the attempt.
Depending on the patent in question, it is possible to be on the hook even if you don't use React.
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.
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.
Close enough, I'd say.
> FB could still enforce patents regardless of license
It is widely accepted that the MIT license has an implicit patent grant.
Out of curiosity, did you switch to Rollup for the tree shaking optimizer, or for some other reason?
Don't expect it to magically improve performance though. But the async stuff mentioned in the post will definitely come to RN when it is ready.
Why remove the dist folder that was in prior releases?
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
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?
It's just not the way things are done in the JavaScript world.
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.
// 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.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.
[0] https://github.com/StreakYC/react-float-anchor [1] https://github.com/StreakYC/react-menu-list
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.
Other times it's lock in for related technologies (current or future plans).
Some have speculated that it's a legal trick, like the problem everyone was insinuating with the React license before the recent change.
Anyone else have reasons I'm missing?
1. Makes it easier to identify talent out in the world that they want to go after.
2. Raises the technical reputation of Facebook, making it easier to get candidates to say yes.
3. Makes it easier to ramp new employees up on Facebook’s stack if they are already familiar with a lot of it from open source.
https://code.facebook.com/posts/300798627056246/relicensing-...
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.
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.
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.
I'm not sure how I feel about this change, but at least there's an escape hatch.
class MyButton extends MyBaseComponent {
// Render a button
}Class MyBaseComponent extends React.Component {
// Include error handling lifecycle hook here
}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.
Congrats on shipping!
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
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.
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).
https://facebook.github.io/react/docs/react-without-es6.html
https://facebook.github.io/react/docs/react-without-jsx.html
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>See also: the docs
Crazy to see such a robust, mature framework still improving so much. Can't wait to upgrade!
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...
https://medium.com/@leeb/relicensing-the-graphql-specificati...
It's also more compatible (which, tbh, is actually more important practically) and that was the main problem with the whole Apache thing.
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.
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...
if fb actually wanted to prevent someone from using react, they could just revoke the copyright grant.
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.
Multiple render return types and portals both solve some annoying situations that can come up.
Fantastic release nevertheless!
or Set: http://kangax.github.io/compat-table/es6/#test-Set
I will probably continue to transpile for the moment (till I can check everything).
There is also polyfill.io which would only polyfill old browsers.
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.
That's a pretty good idea, actually. Thanks for the suggestion!
I strongly doubt I'm the only one there.
The author creates a library, piece by piece, which introduces the same concepts. Makes it much easier to jump into the 'real' framework.
https://github.com/gothinkster/react-redux-realworld-example...
- whether or not this really uses best practices?
- leverages React to the fullest?
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 .
The more important thing to decide is whether the development model of React is suitable for your needs.
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.
The crawler would read it no differently.
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
> Instead of ignoring unrecognized HTML and SVG attributes, React will now pass them through to the DOM.
Does that mean we can start using "class" instead of "className"?
[1]: https://developer.mozilla.org/en-US/docs/Web/API/Element/cla...
[2]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelEl...
const { class } = props
Which is very common and deeply confusing.So even though "class" will technically work now, it will still warn, and ask that you use "className".
(And officially supporting both would make it confusing for third party components since each would have to also support both.)
> 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).
[0] https://facebook.github.io/react/blog/2017/09/08/dom-attribu...
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.
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.
We've added support for returning strings, too:
[…]
See the full list of supported return types.
Why not express that with… ehm… proper types?!? You know… like those used by Flow or TypeScript.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.
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.
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.
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.
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.
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.
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 wants you to use FP
Not at all. It is unopinionated.
You can use Vue as plain JS. You don't lose much by abandoning the single file components.
> React is just Javascript.
Except the entire ecosystem is designed to steer you toward JSX which is not "just Javascript".
const A = () => <div>hello</div>
Is the same as const A = () => h(“div“, null, “hello“)
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.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.
History repeats itself.
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.
- 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.
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?
React is idiomatic javascript. Vue is it's own quirky thing that doesn't feel anything at all like Javascript to me.
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.
Hater-or-lover of JSX, it is definitely an intuitive way to think about HTML in the context of JS.
I prefer the vue model that's a bit closer to the metal, though, if only because of quirks like className
Mithril has "class" instead of "className"; that irks me too.
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:
import timestamp from 'time-stamp'
const Header = props => <h1>{props.text}</h1>
const Main = () => <Header text={timestamp()} />
ReactDom.render(<Main />, document.querySelector('#app'))
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.• 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.
> 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.
I've never coded in React or Vue but after spending 15 mins reading https://vuejs.org/v2/guide/render-function.html here's a pure JS re-creation in Vue for you (fiddle here: https://jsfiddle.net/0wr6xskh/):
<div id="app"></div>
const MyHeader = Vue.component('MyHeader', {
render: function (createElement) {
return createElement('h1', this.text)
},
props: {
text: {
type: String,
required: true
}
}
});
new Vue({
el: '#app',
render: function (createElement) {
return createElement('div',[
createElement(MyHeader, {
props: {
text: ''+new Date()
}
})
])}
});
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#JSXOnce 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.
> 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>
)
Recreate the snippet above, then let's discuss.Also you can use `items.map` in your example.
The example would run without keys, it's merely for demonstration. You'd need keys in Vue as well.
I don't think that's reacts fault? http://exploringjs.com/es6/index.html#toc_ch_first-steps
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.
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.
function Header(props) {
return <h1>{props.text}</h1>;
}
function Main() {
return <Header text={new Date()}/>;
}
ReactDom.render(<Main />, document.querySelector('#app'))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.
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.
Usually not a problem but some issues on Github are in "Chinese" (not sure if Mandarin or Cantonese sorry) so not very helpful.
If you want more choices for those libs (at the cost of potentially more dependency update hell) React is great and more popular.
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.
If there's any huge company that gives engineers relative freedom to build what they want, Facebook is definitely it.
This release is MIT license release after they start losing in front of more real open source frameworks like vue. Better late than sorry facebook!