React v17.0 Release Candidate: No New Features
reactjs.org
reactjs.org
As a mostly Python and only occasional JavaScript developer, it always felt like the biggest challenge in the JavaScript community was how fast everything moved - new libraries, frameworks and ideas would tumble past at the rate of one every few weeks, and it felt impossible to keep up.
I've been feeling that a lot less recently, and maybe the fact that React has been steady for 2.5 years is part of the reason.
Those of us who were doing Python web dev in the years 2000s might remember that Python went through a similar period where it seemed that every week a new backend framework came out: Zope, CherryPy, web2py, Pylons, Django, repoze.bfg, TurboGears... to name a few. Nowadays it seems that everybody has settled for either Django or Flask. It might not have been as crazy as what happened with JavaScript in the years 2010s but still I tend to see a similar pattern. People try a lot of different things, going in slightly different directions and eventually interesting approaches get identified and communities build up around a couple of solutions.
Meanwhile the Ruby community was able to build consensus around Ruby on Rails, with just Sinatra on the side for small projects.
I'm wondering if this ability to try many different things might have been the cause for Python building numpy and eventually winning the scientific computing area as well.
Also it seems JS devs don't understand semver either. Massive breaking changes in patch or minor versions are just evil.
It has a tick-tock pattern so that you can upgrade and having time to fix the warnings.
The API changes are carefully crafted.
Sometimes there are even migration tools to help you upgrade.
I have published a library myself and experienced it, going from 2.x to 3.x to 4.x.
After you just do it for the sake of semver though, the resistance vanished for me.
And the second thing: Never use 0.x.x versions, I think those should have been omitted from semver completely, as they circumvent the entire concept.
A problem in React ecosystem is that it's a rendering library not really a webapp framework so you need to use community provided libraries to fill in the gaps. Those libraries are often maintained by an individual so it's unreasonable to expect corporate SDK approach to development, but unfortunately it leads to a lot of abandonware and rewrites, especially since JS is not very maintainable and it's often easier to rewrite something than to pick up someone else's code.
I am relatively new to React. Perhaps all of this happened 3 or more years ago.
I know React Router 4 was released in mid 2017. Perhaps I was too new when I looked over the changes between 3 and 4. It didn’t seem as drastic as the general opinion that JS changes like crazy. I looked at the migration guide again. Still doesn’t look too bad. Maybe it would be in a large code base.
I try to resist hyperbole, but if it wasn't for the brand value of owning the name "React Router", it should (or would) have been released under a different package name.
Lags behind in server side frameworks adoption over Vue.
React won the enterprise crowd pushing angularjs out.
React hasn't won over the JQuery crowd
If you do primary js it probably has. If you only do some js and other things it probably hasn't yet.
React is at a great level of abstraction between code and UI framework. It reminds me of the MVC frameworks of olde, which by all accounts were great, just limited because they relied on page refresh for everything
React works really well but if I chose it for a personal project today it would only be to avoid switching back and forth, not because I think it is better.
Uh, I'm gonna challenge you to give a source on that. Your comment sounds extremely biased towards React and dismissive towards Angular. None of those are dying out, I wouldn't we even say they compete directly.
Angular does crazy things to the templates, to the point that trying to build your own UI widgets is a recipe for pain.
Template meta-language is stupid. It's just similar enough to JS that you mess up the syntax all the time and never really stop. Since it's not just JS like JSX there's not good linting support either.
Related, stupid "pet features" and hydra syndrome. Like Pipes. Why does Angular use these weird pointless things when you can do the same thing with JS built-ins? Just so they didn't have to copy JSX? We may never know. And why are there 2 form implementations that both feel half baked? Why is it so bad to instantiate components for testing? Why does it mangle the code to support dependency injection when decorators and DI support don't even actually exist in JS even in ES2018? Why is Polyfills.js such a minefield? I could go on but really, why are so many things half assed and haphazard. It reminds me of Go...
Constant "expression changed after it was checked" errors because the data model change tracking is fundamentally broken
Repeated refactoring of HTML form interop and it still kinda sucks
Major breaking changes on nearly every upgrade that take days to do, even on our small apps.
Crappy documention. There's no usage examples for most of the library, just the Angular version of Javadoc.
Terrible bike shedding by Angular and Material teams. I'm following a bunch of issues and I've never seen one closed. I've been following some of the threads for years.
That was a nasty rant but I have plenty of things to hate about Angular. React on the other hand has a mostly clean core API and doesn't force all this baggage on you. IMO this has spawned a competitive ecosystem where the bad ideas get shaken out. Angular is stuck in the past and feels creaky compared to React development these days.
JSX is the future. It's exactly how MVC frameworks used to work, and it would be popular for templating even if the rest of React didn't exist. Change tracking with props is another. It's simple, it works. Angular change tracking errors are the segfaults of front end dev
Sounds like are doing something wrong. At least I can't remember that particular one from three years of Angular >=2
> Repeated refactoring of HTML form interop and it still kinda sucks Major breaking changes on nearly every upgrade that take days to do, even on our small apps.
I did most of upgrades for over a year I think. They were mostly trivial after reading up on the changes and I don't consider myself a 10x engineer. Pro tip: Learn to use this repo: https://github.com/cexbrayat/angular-cli-diff
> Crappy documention. There's no usage examples for most of the library, just the Angular version of Javadoc.
Not perfect (internal inconsistentencies where one paragraph says "don't do this" and a couple of pages down they do exactly that).
But far far from Javafoc.
> Terrible bike shedding by Angular and Material teams. I'm following a bunch of issues and I've never seen one closed. I've been following some of the threads for years.
I don't like Material either ;-)
For everyone else:
Like always: keep it simple. Stick with the standards. Use a good ide/editor. Use Angular CLI, stick to the style suggested by that even though you don't have to use it for every small thing.
Versus 2016: http://2016.stateofjs.com/2016/frontend/
Angular is 100% fading, albeit slowly. Seems like a lot of slow moving enterprise companies are still going with it anecdotally. I'd bet on very few new projects opting for it currently, and probably near zero within 2-3 years.
As to why, IMO Vue ate Angular's lunch. Single file components did everything angular's MVC wanted without all the failures like $scope and other things. React and Vue can coexist, but I think Vue and Angular are direct competition. Also see those developer surveys and the massive growth of popularity of Vue along with angular's fading.
You're right that MVC no longer applies, but Vue's components still beat Angular 2+ and the dev world seems to have spoken pretty loudly about feature preference/priority, and many of those mean Vue over Angular while leaving React a bit more in its own world.
https://trends.google.com/trends/explore?date=today%205-y&q=...
Feature-wise, Next does seem like a superset of Gatsby, especially since it can support server, static and hybrid rendering models. Architecturally, Gatsby does have some advantages. They're not ones that are particularly important to me, but I don't think it's fair to ignore them:
- The plugin model is more sophisticated, and there's a huge ecosystem of them which can solve most common use cases.
- The ability to use a unified data graph means page invalidation and rebuilds upon data changes can be done automatically at a very granular level -- because it's possible to keep track of which pages would be affected by every piece of data.
I'd add that I have issues with both, which leads me more to Next.js because it has a lower level of vendor lock-in compared to Gatsby. Anecdotally, migrating a small site from Gatsby to Next.js replaced 150 Gatsby-related imports with 10 Next.js ones.
For those, it is much more easier to add vue as a script tag. also easier to setup Vue, compared to react.
What do you mean by this? Which server-side frameworks? Are you comparing Next and Nuxt?
Server side frameworks (the usual favourites) have existing ways for code to result in HTML. Ruby/PHP/Java -> HTML
Vue on the other hand can sit within HTML. So you can sprinkle in client-side logic in the views while still generally going with the grain of your server side framework.
https://gitlab.com/gitlab-org/gitlab/-/blob/6cece3f49eb87779...
See `if can?(current_user, :admin_issue, @project)` (Ruby) and `"v-if" => "issue.labels.length === 0"` (Vue)
Over here it is all about Angular and Vue, and this for a minority of projects.
The large majority is done on SSR, CMS based infrastructure with vanilaJS.
If you don't like things moving too fast, then React does seem to be the ideal ecosystem:
https://github.com/facebook/create-react-app/issues/9033#iss...
TL;DR A vulnerability was discovered in a transitive dependency of "create-react-app" and announced back in March, but the one line patch to update the hard-coded reference to the vulnerable version is being held back for a future major version upgrade of the "create-react-app" package. 5 months on and the issue is marked as Closed but the new version hasn't been released.
While I agree that ideally a release should be cut to satisfy people affected by enterprise requirements, we are looking at a case of an overzealous audit checker, not an actual vulnerability that affects your apps.
(Edit: I've cut a release though; see my response in https://github.com/facebook/create-react-app/issues/9033#iss...)
I think that the real concern was not the non-existent security implications (although it's a bad habit to ignore even an overzealous audit checker), but that the release process for CRA seemed to make it very hard to cut new patch releases. Your comment suggests that it wasn't so hard after all, for which I am relieved and grateful, but the policy of expecting people to wait for (and deal with the backwards incompatibility of) major version updates[0] doesn't feel like an industry best practice.
[0] https://github.com/facebook/create-react-app/issues/9033#iss...
Can someone on the React team speak to how event delegation works when there are portals present? Where is the event handler for a portal bound, and how does the new events system handle event bubbling across multiple versions of React in portal trees?
I can't speak to the exact semantics of how portals work with nested trees, but if you find an issue, please file one on our tracker. Some are expected to be impossible to solve, but hopefully we handle the common cases well.
(I would ask Dominic who worked on this but he just went on a much needed holiday break.)
Thanks for maintaining backward compatibility, which is not very common in the JS world. And congrats on the release!
Class components are so stupidly simple to read and write. I appreciate the work put into function components, but to me they make things unnecessarily complex. Just the fact that they took callbacks and other functions from methods – where things are separate, clean, standard – to nested functions – where things are not separate (some local variables, some closure variables), not clean (no possible way to unit test a nested function in isolation), and not standard (object methods are a language feature, use them!) – seems like a huge step backward.
By creating `bridge` release, the React community created a safe, well know and stable release that works as bridge for the upcoming complex, feature rich, release.
So: Complex Release -> Stable `bridge` Release -> New Complex Release.
Anyone can stay as long as they want in the bridge release, others can quickly move forward to the next release cycle.
const [x, setX] = useState()
useEffect(() => {
let isMounted = true
someAsyncFunc(result => {
if (isMounted) {
setX(result) // should not be called on dismounted component
}
})
return () => { isMounted = false }
}, [])
return <MyComponent x={x} />
In this example it's possible that component will be unmounted, then completion handler will run and try to modify state before cleanup function will be able to set the flag.Imo choosing a different name for new useEffect would be better (like useAsyncEffect or introducing a parameter), because just changing its behavior won't even result in compilation errors or guaranteed run-time errors, only make old code unstable.
Is there a way to reliably detect if component is still mounted before updating it when doing async operations in effects?
So code like this can stay written exactly as it does today. As noted in the blog post we’ve only had to modify ~20 components out of thousands so although this change may cause some breakage (please report anything unusual to the issue tracker!) we’re fairly confident that such common patterns continue to work.
(Edit: added this to the post.)
Thought about making a lint for it but never got around to it.
https://reactjs.org/blog/2020/08/10/react-v17-rc.html#no-eve...
<MyList items selectedItem onItemClicked />
Doesn't seem too likely to happen at this point, though. <MyList {...{items, selectedItem, onItemClicked}} />
There's a lot of "gets you most of the way there" hacks with JSX that will fill most needs. Where as you can imagine the incredible cacophony of screaming developers who maintain TypeScript, Preact, IDEs, etc. that would be incensed by breaking changes to JSX introduced just to solve some inconveniences.Doesn't mean the syntax _can't_ change . After all, the `<>` shorthand syntax for fragments was added via cooperation with the Babel and TypeScript teams, and the work on the new `jsx()` replacement for `createElement()` is going the same way.
What would happen with <input disabled /> then?
What if there is a global disabled var?
I really dislike the way they can be abused to litter state and side effects all over React code so easily (e.g. hiding it layers deep in helper functions). And I feel they've made the API worse, such as `this` being replaced with the more clumsy `useRef`, or requiring an empty array to change the behavior of `useEffect`. These are things that break the Principal of Least Astonishment and have consequently led to countless blog posts that try to explain how to do things that were much more straight forward without hooks.
I've written about hooks before in past comments: https://news.ycombinator.com/item?id=19357068
It's been a couple of years since they've been added, and I don't feel the ecosystem has improved because of it. So to me it was a mistake.
I know they will likely not be removed from React, so what I said was more tongue-in-cheek.
It makes it much easier to have composable functions/state, which I love.
They certainly work when you memorise the rules and syntax, but it feels very contrived even when it all makes sense.
This drives me a little crazy too. That behaviour can be easily documented by wrapping it in a function with a name that makes sense, but people litter their React code with non-obvious hooks everywhere. You can reduce a lot of boilerplate (why are you writing empty arrays everywhere!?) and improve readability substantially by wrapping the hooks in more composed and idiomatic functions.
I think that was along the lines of what was intended for hooks, but I don't see it often.
I'm sure the React team must be eager to get all the juicy changes out of the experimental branch and into the hands of developers. So it's great to see though that they're still taking their time to do it properly. Looking forward to seeing what come nexts :)
Yet more excess JS downloading and running on client devices, all in the name of superior developer experience. I hope my cynicism is proven wrong!
It's very suboptimal but I think it's still better to have that option than not to have it — or to try it and run into insurmountable problems. Especially in big long-running projects like internal company dashboards where long-term maintenance is more important than time to first render.
(I don't know why you're being downvoted though! I think your concern makes a lot of sense, and we're also sensitive about how to balance the messaging so that people don't use this unnecessarily.)
https://github.com/angular/angular/issues/37293
I have 2 comparable applications (in size) and React build times are 10 times faster than Angular.
And as you write larger and larger apps, with hundreds of components, it's just ridiculous how poorly the first-party tools handle that kind of code scale. Your only choice it to buy into Bazel to maintain some sense of sanity and productivity albeit some of which gets diminished with the overhead of learning, using and maintaining bazel for the project.
Complexity on top of complexity, nothing about Angular is simple.
Allowing code to be properly ready and tuned for the next major release. Where the new features will be actually introduced, hopefully, without new bugs.
By all means make breaking changes, just maybe tone down the marketing.
In my opinion this goes WAY beyond the usual changelog entry in other repositories.
I think it's important to understand though that React is _marketed_, and unfortunately for many a name as clearly stated as this will likely define their expectations significantly. This could be especially pronounced for those who are less proficient in English.
I wish macOS / iOS / iPadOS would have a version without tons of new features.
We've had similar releases since then which added a few new features but were primarily focused on stability. The most recent one was High Sierra. These do tend to be the best releases of macOS IMO.
But yeah, I'm mostly just referring to quality-of-life improvements as being a focal point of the release.
I only worked on documentation and presentation.
Personally I don't like the design pattern, a matter of taste. But it's very annoying now in the market to have mixed React and Hooks codebases, with all their issues..
https://reactjs.org/docs/hooks-faq.html#what-is-the-prior-ar...
Our official Redux Toolkit package [0], which is now our recommended approach for writing Redux logic, _does_ have a few more deps: Immer, Reselect, Redux-Thunk, and the Redux core. But, those are all things you probably would have had in your app anyway.
If you're not familiar with Redux Toolkit, it includes utilities to simplify several common Redux use cases, including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state at once.
I just published a brand-new "Redux Essentials" core docs tutorial [1], which teaches beginners "how to use Redux, the right way", using our latest recommended tools and practices. I'd encourage folks to check it out.
[0] https://redux-toolkit.js.org
[1] https://redux.js.org/tutorials/essentials/part-1-overview-co...
I'm too out-of-the-loop these days to know what Immer is, will have to give it a look.
Quick summary:
Immer is an incredibly useful immutable update library, created by Michel Weststrate (author of MobX).
It exports a single function `produce(originalState, updateCallback)`. The callback receives a `draftState` value that _looks_ like your original state, but has been wrapped in an ES6 Proxy. You can then "mutate" the draft all you want. Internally, Immer tracks all the mutations, and the final result is a safely immutably-updated value.
It drastically simplifies immutable update logic - no more nested spread operators!
See https://immerjs.github.io/immer/docs/introduction and https://redux.js.org/recipes/structuring-reducers/immutable-... .
Redux Toolkit comes with Immer built into our `createReducer` and `createSlice` APIs automatically.
But then a couple of weeks later I had to wrangle data in subsections of three “slices“ of state at the same time.
Immer lets you focus on just the state you want to change, and hides the problem of maintaining the state you don’t want to change. Brilliant. I’ll take the “it looks like mutation” hit for that.
Immer just does that in a really slick way.
My only concern for using Immer by default in RTK is the potential that someone would learn Redux by osmosis through looking at a codebase where every reducer is doing `state.someField = someValue`, think that actual mutation _is_ the right way to use Redux, and then try to do the same thing in another project and actually mutate data for real.
I can't prevent that, so my only answer was to repeatedly emphasize in this new tutorial that you _must_ do immutable updates, and that you can _only_ "mutate" inside of RTK's APIs thanks to Immer:
- https://redux.js.org/tutorials/essentials/part-2-app-structu...
- https://redux.js.org/tutorials/essentials/part-3-data-flow#s...
But yeah, the massive improvements in code size and readability are more than sufficient to justify the small potential downside there.
Gasp! Will redux store no longer be an observable then?