13 ms·
React v16.3.0: New lifecycles and context API
- SamLevin88 9y agoLot of niceties in this one. Painful to keep up at times but at least the React team makes it worthwhile for those who do so. Kudos.
- m0meni 9y agoSummary: * Context overhaul that makes it way easier to pass state/props down multiple levels of components. Uses function as a child for the API * Adds React.createRef function to create refs. Creating refs through callbacks is still a thing for advanced cases, but this provides a more ergonomic API to replace the old clunky ref={(c) => this._yourthing = c} type callback. * Adds React.forwardRef, which solves the issue of HOC not passing refs to the component they're wrapping. * Lifecycle methods (componentWillMount, componentWillReceiveProps, and componentWillUpdate) are now considered legacy, and will be deprecated in future releases. To replace them, they added two new ones (getDerivedStateFromProps and getSnapshotBeforeUpdate). This is due to these lifecycle methods interfering with the goals of async rendering and other ambitious ideas. * Adds a StrictMode component, which basically just causes React to log more errors during development about deprecated/legacy APIs and unexpected side effects.
- danabramov 9y agoNote: createRef doesn’t replace callback refs. It just offers a more ergonomic API for common use cases. There are still rarer cases where callback refs are useful. For example when you need to run a side effect on a node as it attaches and detaches. Also note: legacy lifecycles are not deprecated yet. You won’t see the warnings unless you opt in with <StrictMode>. They will be officially deprecated in a future minor release when more libraries have had time to update.
- hoodoof 9y agoOff topic but Dan - referring to your question to me yesterday I'm curious to your answer: You asked "Curious, what do you use it for?" in regard to componentWillReceiveProps https://news.ycombinator.com/item?id=16695064 https://news.ycombinator.com/item?id=16695064 I use componentWillReceiveProps for just about everything - I had thought it was a fundamental part of the Redux flow. i.e. Redux updates, new props flow through the hierarchy, I pick that up in componentWillReceiveProps and make changes based on new props. Is this not correct?
- spicyj 9y agoLet's keep the discussion on that thread – I just responded there.
- brianvaughn 9y agoThe purpose of componentWillReceiveProps was to update state in response to props changes. (This is also the purpose of getDerivedStateFromProps.) What you're describing sounds more like you're updating something external (e.g. your Redux store). This isn't what the lifecycle is meant for, and you'd be better off using componentDidUpdate instead.
- deleted 9y ago[deleted]
- spicyj 9y agoNote that we have no current plans to deprecate componentWillUnmount. (Edit: Parent originally said "componentWill*" deprecated.)
- k__ 9y agoWhat would the alternatives to it be anyway?
- m0meni 9y agoI'm curious that with the addition of APIs like forwardRef, if it wouldn't make sense to just add some HOC helper that does the HOC ceremony for you. For example, if you look at withRouter[0] from react-router 1. you need to set the display name 2. you need to set the wrapped component 3. you need to hoist statics 4. and with this update, you'd forward refs Granted, I could just write it myself real quick, but it'd be nice to just have an API you could use that doesn't require you to fully grasp all the complications that come with using a HOC. I've recently just deferred to using render props instead of HOCs. Render props also require way less complex type definitions if you're using flow or typescript. [0]: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/withRouter.js https://github.com/ReactTraining/react-router/blob/master/pa...
- WhitneyLand 9y agoDeveloper learning curve: The context name is a good choice I think. Context API sounds much more elegant than global variables API. While that’s a little tongue in cheek, the lifecycle method names I would rate as a drastic drop in intuitiveness: Previous: componentWillMount componentWillReceiveProps componentWillUpdate New: getDerivedStateFromProps getSnapshotBeforeUpdate
- danabramov 9y agoThis is intentional because those are relatively rare use cases. We want them to stand out and be quite specific about what they're doing. You still have `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` that should be used more commonly and do exactly what you expect them to.
- djhartman 9y agoIn your experience, what are the kind of things that people do in `componentWillMount` that they shouldn't be doing? Is it correct to say that `getSnapshotBeforeUpdate` is named to indicate what you were supposed to use `componentWillMount` for? Thanks to you and brianvaughn for answering so many questions.
- brianvaughn 9y ago> In your experience, what are the kind of things that people do in `componentWillMount` that they shouldn't be doing? The biggest one is probably adding event listeners or setting up subscriptions (which can cause memory leaks). Here are some others: https://github.com/reactjs/rfcs/blob/master/text/0006-static-lifecycle-methods.md#common-problems https://github.com/reactjs/rfcs/blob/master/text/0006-static... > Is it correct to say that `getSnapshotBeforeUpdate` is named to indicate what you were supposed to use `componentWillMount` for? No. `getSnapshotBeforeUpdate` is not really related to `componentWillMount`. It relates more to what people were using `componentWillUpdate` for.
- ssahoo 9y agoReact API reminds of Microsoft COM for JavaScript. It was called Component Object Model. It was hell to deal with when lasted.
- swalsh 9y agoI'm old enough to remember COM, besides the word component, what's the similarity?
- matthewmacleod 9y agoThere is… just no similarity whatsoever.
- seattle_spring 9y agoQuintessential "tech is so ageist!" comment. Well done.
- hardwaresofton 9y agoThe downvotes are unfortunate, since this is a reasonable sentiment, here's an article I read a while ago that presented this point in a more nuanced fashion: https://bitquabit.com/post/the-more-things-change/ https://bitquabit.com/post/the-more-things-change/
- acemarke 9y agoCOM and a Win32 WndProc function aren't very similar :) (And yes, that's a very good post.)
- hardwaresofton 9y agoAhh I thought they were the same -- admittedly I've never worked deeply with windows program (and do not plan to at any point in time), so I couldn't tell the difference
- swalsh 9y agoIn the unlikely scenario of Facebook's demise, how do you think the maintenance of React would transpire? Do you think some other tech company would snatch up the design leads, and pick up the torch? Would it go into its own independent organization?
- hysan 9y agoMy bet would be on someone like Expo taking up the reigns and putting in place a way for the community to keep it going.
- matte_black 9y agoReact could easily spin off into its own org funded by donations.
- hoodoof 9y agoThere is no demise coming for Facebook. They'll clean up, grandma, aunty and the school mothers will continue posting and they never even knew there was an issue. People will soon forget.
- navls 9y ago> Will MySpace ever lose its monopoly? [2007] https://www.theguardian.com/technology/2007/feb/08/business.comment https://www.theguardian.com/technology/2007/feb/08/business....
- Bahamut 9y agoFB is on a whole different level in terms of revenue (and profitability) and users. While it may be possible that FB fails, there’s not a whole lot of symptoms apparent that it will, unlike MySpace.
- hashbig 9y agoPeople that keep comparing FB to Myspace simply don't understand scale. Having 2 billion users is not a 1000x better than having 2 million ones. It's more like a million times. The network effect compounds non-linearly. Facebook (the company) is here to stay. Even if the product is gone, they own 2 other multibillion dollar social networks: Instagram and WhatsApp.
- eric_b 9y agoI like that they are taking the deprecation of the lifecycle methods slowly. And the automated script to migrate to the 'UNSAFE' version of those methods in 17 is a nice touch. I don't know if I love the new context API, but it's great they're giving an official option. Of the big JS frameworks that are popular at the moment, I think the React team is doing the best job of balancing new features with minimizing developer pain and breaking changes. If I had one thing negative to say about this release, it's that I think the forwardRef is maybe moving in the wrong direction a bit. In my experience, higher order components should be the exception, not the rule. They are a neat way to provide some functionality that is otherwise difficult, but their cognitive and maintenance overhead are high. If it stops at forwardRef, no big deal, but I am not sure HOCs are something that deserve explicit API support (and the additional surface area that entails)
- brianvaughn 9y agoHOCs are widely used (and for good reason– they can be very useful). Hopefully forwardRef will make their usage more consistent and predictable. If anything, I think the new context API (and even forwardRef itself) are endorsements of the render prop pattern more than of HOCs. :)
- zackify 9y ago“higher order components should be the exception, not the rule.” This just isn’t true. Abstracting form logic. Request logic. Anything else you use across your app. Connect in redux. There are hundreds of good reasons to have a higher order component. It makes testing easy. Test your request logic in one place, anything that uses it is now a stateless component, and testing it is trivial.
- underwater 9y agoRender props can solve many of those problems without Higher order components.
- hungerstrike 9y agoNo, they should still be the exception for the reasons already stated but also because defining all logic in a “render” function means it’s tightly coupled to your view logic, which you do not want. Request logic doesn’t belong in a render function. Routing definitions don’t belong in a render function and neither does abstract form logic.
- deleted 9y ago[deleted]
- hoodoof 9y agoAny example anywhere of using context for current authenticated user?
- brianvaughn 9y agoNo, but you could do it in a similar way as the "Dynamic Context" example [1] - store the authenticated user/status in component `state` and pass it down via a AuthenticationContext.Provider. Then anything that needs to know about it could use the AuthenticationContext.Consumer. 1: https://reactjs.org/docs/context.html#dynamic-context https://reactjs.org/docs/context.html#dynamic-context
- CuriouslyC 9y agoI have very mixed feelings about the new context api. On one hand, you're taking a foot-gun away, which I approve of having worked on code bases that abused it. On the other hand, it's very clunky, and I think people who abused the old context will just start making components larger, and wrapping them in a single context, rather than doing the right thing with many small components individually wrapped. Personally I think props inheritance, with IsolatedComponent as an escape hatch/boundary would have been much cleaner.
- brianvaughn 9y agoWould you elaborate on what you find clunky about the new context API? :)
- CuriouslyC 9y agoWell, I tend to make a lot of very small stateless components. If a component is 1-6 JSX tags, the new context API represents a boilerplate overhead of between 100 and ~17%. Additionally, the semantics of having a consumer's props.children be an immediately invoked function are a little bit unintuitive to me. I think having multiple ways to pass "props" increases the api surface area, having everything "just be props" would be simpler.
- brianvaughn 9y ago> Well, I tend to make a lot of very small stateless components. If a component is 1-6 JSX tags, the new context API represents a boilerplate overhead of between 100 and ~17%. Not if you use a HOC (e.g. `withContext(Component)`) like a couple of the docs examples showed. > Additionally, the semantics of having a consumer's props.children be an immediately invoked function are a little bit unintuitive to me. That's fair! I would encourage you to give it a chance though. I think it's a pattern that really grows on you after a short time. :)
- danabramov 9y agoWhat is props inheritance and IsolatedComponent?
- nkkollaw 9y agoI use and love React, but I'm also a little scared of it. I opened this little app I did 1 year ago in React 15, and it's completely incompatible with what I use now. Every time I read of a new release I get this chill down my spine for a second.
- brianvaughn 9y agoOur upgrade process is very gradual. As long as you've fixed all of the dev warnings for the last minor release of a given version, you should be able to upgrade to the next major without any problem.
- wolco 9y agoFor someone who hasn't opened the app in three years going through the upgrading process for each major version/minor high version would be more difficult vs rewriting for most smaller components. To the parent's parent's point Javascript has evolved since 2015 and comparing what a 2015 app looks like to a 2018 app is day and night.
- brianvaughn 9y agoUpgrading any project after 3 years of inactivity would be difficult, regardless of framework. I did not mean to imply that you would need to step through every minor version though. I was just saying that- if you were using e.g. 15, update to the latest 15 release (15.6.2) and fixing warnings in it before updating to 16.
- nkkollaw 9y agoThe problem is when--like in my case--people develop a project for a client and then go on with their lives, until the client notices a bug, or wants to implement a new feature months after. I tried to explain the client that I needed to upgrade the code before even being able to understand what the problem was, and I lost the client. As much as they suck, PHP apps from 10 years ago are still working great, and so are jQuery-based apps from 5 years ago. Would never go back to either one, though.
- jdpigeon 9y agoI've been thinking about different situations in which Redux could be replaced with the new Context. Id sure appreciate having to write less boilerplate. The biggest concern I always get stuck on is where I'll put all my app's business logic, which I'm so used to putting in async redux-observable or redux-thunk actions. Does anyone have anything ideas on how to make an elegant business-logic-full Provider component?
- acemarke 9y agoI put up a post today called "Redux - Not Dead Yet!" [0], where I responded to recent comments claiming that the new context API will replace Redux. (Answer: maybe, if all you need is just passing down data to deeply nested components.) As for the "boilerplate" topic: you are encouraged to use as little or as much abstraction on top of Redux as you want, whether it be small utility functions or entire other frameworks that wrap Redux. We've got a "Reducing Boilerplate" page in the docs [1], and I've got a section of my React/Redux links list for articles on that topic [2]. I'd be happy to suggest possible solutions for whatever problems you're concerned about. [0] http://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet/ http://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet/ [1] https://redux.js.org/recipes/reducing-boilerplate https://redux.js.org/recipes/reducing-boilerplate [2] https://github.com/markerikson/react-redux-links/blob/master/redux-techniques.md#reducing-boilerplate https://github.com/markerikson/react-redux-links/blob/master...
- bcherny 9y agoIf you want less boilerplate and type safety, consider Undux - https://github.com/bcherny/undux https://github.com/bcherny/undux
- hardwaresofton 9y agodisclaimer: I don't like react. Outside of dom node diffing and a focus on components I don't think it brings much to the table considering the considerable complexity it brings. It seems like react gets re-written and APIs undergoes drastic changes every few months. I'm not complaining about churn (I don't write react), but rather that maybe React isn't the right tool to be hyping up, or pointing newcomers to JS at to look into/use. I don't remember any other supposedly simple library having had this many major rewrites/api changes. I don't think I've ever seen something like this in KnockoutJS or even Angular1 for a long time (even though the way you had to handle $scope and apply/digest cycles was terrible). Relative newcomers like Mithril and Vue seem to get this stuff right without requiring as much breaking changes. Maybe they owe their simplified structures to some of the new thought to what React inspired, but it seems like they're actually simple (Vue's documentation is amazing, concise, and you can actually render Vue in the browser to get started quickly). Maybe it's time to rethink whether React is a good tool. There's no way I would recommend React to anyone (beginner or intermediate) over something like Vue these days. For example, I don't know what HOC (and am thoroughly uninterested, it sounds like the same kind of thing you only need to know when you're chest-deep in React land) is but it sounds like a hack necessary because of a bad design decision. [EDIT] - Took a few seconds to look up HOCs (Higher Order Components) and they're a bad example of what I think is incidental complexity inside React but I think my point still stands. To clarify, here's my thesis: React is complex (both internally, evidenced by multiple rewrites, and with the tooling it forces you to use, evidenced by needing to download a zip file to start, or touch webpack), but masquerades as a simple library.
- acjohnson55 9y agoFor the most part, the changes really shouldn't affect typical users. The biggest change in React from a dev perspective was function components, maybe 2 years ago. If you keep your state outside of React, it's dead simple to use. I think it's a great library and has only really gotten simpler and better. But, to each their own.
- hardwaresofton 9y agoI agree that it's getting simpler and better -- tons of dedicated developers are making that happen. I wasn't trying to say that the rewrite shouldn't have happened or something, I just feel like there's a lot of zealotry festering, so many companies are picking React just to attract developers (anecdotal evidence: https://www.youtube.com/watch?v=u80GTmVtdG4&t=2898s https://www.youtube.com/watch?v=u80GTmVtdG4&t=2898s). My problem is that it was being marketed (heavily) as simple and amazing at the beginning when it simply wasn't. From what I remember, the FB team was explicit about it not being for beginners, but the amount of marketing and trumpeting made that basically impossible, and now bootcamps are teaching it to beginners. I just am super tired of having to talk people out of using it on their first project after learning and using HTML+CSS for the first time. I always sound like the insane person, saying "react is complicated" when all the marketing and blogs and everything else is saying "react is simple".
- myth_drannon 9y agoDoes anyone finds the new getDerivedStateFromProps adds too much boilerplate code for the developer to write and be aware? So for every previous prop that I need to compare with I need to remember to update it in the state? If before it was as simple as this.props.X!==nextProps.X now I need to set the state with the current prop!
- danabramov 9y agoThis lifecycle exists for a fairly rare use case. Why do you use it often? Instead of keeping state “in sync” with the props, can you just read it from the props? For the rare cases where you do want to retain previous props, yes, we’re asking you to be explicit about it. This will allow better memory usage in future versions of React, and also avoids the need for an extra `prevProps !== null` check that would need to happen in every `getDerivedStateFromProps` method.
- akrumel 9y agoResponding to "exists for a fairly rare use case" statement, I just searched the the web app I am currently writing and it uses componentWillReceiveProps() ~20 times. Most cases are for detecting changes requiring freeing/fetching network based resources where the data involved can get excessive if care is not taken. This would seem to be a common scenario for many domains. On a sidenote, I have thoroughly enjoyed working with react and RN over the last 4 years and have learned much from dan's work. Thanks guys.
- danabramov 9y ago>I just searched the the web app I am currently writing and it uses componentWillReceiveProps() ~20 times. How many components do you have? Absolute number doesn’t tell me a lot. :-) >Most cases are for detecting changes requiring freeing/fetching network based resources where the data involved can get excessive if care is not taken. Not sure I fully understand. Could you provide a small example?
- 9y ago
- steve_taylor 9y agoThese lifecycle changes make me nervous. We’re losing some important escape hatches to make way for async rendering which solves a problem that very few web apps have. To use an analogy, it’s like “unsafe” features being deprecated in C to make way for the next major release which will be more like Java. My first impression of this is that it’s the beginning of the end for React. People can still use old versions, but the reality is that they’ll have to stick with old versions of related libraries and they’ll have to shrinkwrap their node_modules because these drastic changes are being rolled out in minor version updates.
- danabramov 9y ago>async rendering which solves a problem that very few web apps have. From my experience of talking to React developers, data fetching is the most common problem people bump into with React apps. Async rendering is key to making data fetching easy and natural in React, and to providing a great user experience whether the user is on a fast or a slow network. Please watch the second part of my talk for a demo if you’re not convinced: https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-... >We’re losing some important escape hatches We believe that the combination of new lifecycle hooks and the non-legacy old ones covers all use cases we are aware of (including escape hatches!). If we missed some use case you relied on, we are asking you to let us know: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#other-scenarios https://reactjs.org/blog/2018/03/27/update-on-async-renderin... Escape hatches are core to React’s philosophy. To reiterate a point from the blog post, we have more than 50,000 React components at Facebook, and they aren’t going to rewrite themselves :-). So we are committed to both supporting those lifecycles under `UNSAFE_` aliases (as mentioned in the blog post, they will continue working in React 17), and will provide async-safe hooks for use cases we might have missed (please report them!) Thanks.
- steve_taylor 9y agoI watched the video and I’ll keep an open mind. I really hope you will hold off deprecation warnings until 17.0.0 instead of 16.x, even if that means you need one more major version than you had planned. Being on a team whose policy is to not shrinkwrap, so that we automatically get patches (not my policy, personally), at some point we’re going to start seeing all these deprecation warnings without having explicitly version-bumped React. My overall concern is that we’re paying for the async renderer by moving to a higher level of abstraction for all class components. With Fiber, React is becoming a vastly different library. From the outside, having seen Fiber slated for release in 16.0.0 and, being pushed back to an unknown 16.x release, and then being pushed back to 17.0.0, it seems like you had not anticipated the extent to which the core React API had to be changed to enable the async renderer. It seemed simple enough in the beginning, but now we’re looking forward to losing what React once was so we can use a DOM renderer that will be optional anyway.
- brlewis 9y agoCan someone point me to reasonably simple but not contrived examples that put createContext and forwardRef to good use? As I look at this from a Mithril perspective the value isn't obvious.
- brianvaughn 9y agoThe `withTheme` HOC uses `createContext` and `forwardRef`. I don't think it's contrived. :) https://reactjs.org/blog/2018/03/29/react-v-16-3.html#forwardref-api https://reactjs.org/blog/2018/03/29/react-v-16-3.html#forwar...
- BigJono 9y agoContext is a way to pass state down the component tree without it having to go through intermediate nodes. Say context doesn't exist, and you have a branch of components A -> B -> C, if C depends on some state in A, B would have to have a dependency on that state too. And you'd need some boilerplate code in B that reads the props from A, and passes them to C. If you want to use C in a different context, say A -> D -> C, then that boilerplate code needs to exist in D as well. With larger apps, containing large component trees, the amount of this boilerplate prop-passing you need to do starts to get excessive. It's not uncommon to see components read 14 props from their parent, use one of them, and pass 13 to their child(ren). Until now, this problem has been solved by using data stores that inject state anywhere in the tree that they please. Context is an alternative to that. It's always existed, just now it has a new API. I have no idea what was wrong with the old one. Nobody seems to have properly explained it anywhere, the docs just make condescending suggestions not to use it without reasoning. I think I saw an arcane tweet once explaining that certain things may not have re-rendered properly when using the old API or something...
- GenKali 9y agoAFAIK the problem with the old context is that values in context were not used to determine whether or not the component tree should update. So if a context value in A changed, but no props/local state changed, it would not redraw the tree below it (B -> C). If C's render depended on the context value, it would not be redrawn to reflect the change.
- deleted 9y ago[deleted]
- dereke 9y agoI was hoping they were going to simplify the lifecyles but it looks like they are adding more. Since I switched to hyperdom[0] I haven't missed lifecycles at all. In fact my app has practically none of the "plumbing" code that my old react apps seemed to have. Hyperdom is so much simpler but seems to be just as powerful. [0] http://github.com/featurist/hyperdom/ http://github.com/featurist/hyperdom/
- brianvaughn 9y agoLifecycles aren't mandatory in React. Pure functional components don't use them. Stateful class components don't necessarily need them either (although they _can_ be useful, particularly when interfacing with imperative APIs like the DOM). I've never used Hyperdom, so this isn't meant as a criticism or commentary on it.