Hacker News new | ask | show | jobs
by m0meni 3007 days ago
Summary:

* 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.

4 comments

I'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/pa...

Note: 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.

Off 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

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?

The 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.

Let's keep the discussion on that thread – I just responded there.
Developer 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
This 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.

In 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.

> 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...

> 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.

Note that we have no current plans to deprecate componentWillUnmount. (Edit: Parent originally said "componentWill*" deprecated.)
What would the alternatives to it be anyway?