React: Plan for Addons in React 16

Created on 17 Mar 2017  Â·  28Comments  Â·  Source: facebook/react

Here’s my outline of what I think we should do with addons in React 16.

TLDR: we’ve done a poor job of supporting them, and they pose a significant maintenance burden due to how our repo and build process is set up. We’re going to release final versions for them, and won’t be maintaining them further.

Plan: Don’t Do Anything

react-addons-perf

Internal dependencies (will break in 16):

  • react-dom/lib/ReactPerf

Plan for 15.5: don’t do anything.

Plan for 16: we won’t be releasing 16 for this package. Right now there is no migration path planned for it because Fiber works differently. Instead, you would use the browser Timeline integration (or polyfill it in your environment). We may later reintroduce something like ReactPerf, but in the renderers themselves. However, just like it took us a while to figure out how ReactPerf should work, it will take us a while to figure out a better alternative that would be compatible with Fiber.

Plan: Fix and Forget

react-addons-create-fragment

Internal dependencies (will break in 16):

  • react/lib/ReactFragment

Plan for 15.5: copy internal dependencies into the package to make sure it works standalone. Ensure there is a UMD build in the standalone package, and that it is documented in package's README. Make sure that accessing it via React.addons.createFragment (but not via the package) warns once and suggests using UMD build instead. Release 15.5 without a peer dependency restriction on react and forget about it forever.

Plan for 16: we won’t be releasing 16 for this package. Nevertheless version 15 should keep working indefinitely.

react-addons-linked-state-mixin

Internal dependencies (will break in 16):

  • react/lib/LinkedStateMixin

Plan for 15.5: copy internal dependencies into the package to make sure it works standalone. Ensure there is a UMD build in the standalone package, and that it is documented in package's README. Make sure that accessing it via React.addons.LinkedStateMixin (but not via the package) warns once and suggests using UMD build instead. Release 15.5 without a peer dependency restriction on react and forget about it forever.

Plan for 16: we won’t be releasing 16 for this package. Nevertheless version 15 should keep working indefinitely.

react-addons-pure-render-mixin

Internal dependencies (will break in 16):

  • react/lib/ReactComponentWithPureRenderMixin

Plan for 15.5: copy internal dependencies into the package to make sure it works standalone. Ensure there is a UMD build in the standalone package, and that it is documented in package's README. Make sure that accessing it via React.addons.PureRenderMixin (but not via the package) warns once and suggests using UMD build instead. Release 15.5 without a peer dependency restriction on react and forget about it forever.

Plan for 16: we won’t be releasing 16 for this package. Nevertheless version 15 should keep working indefinitely.

react-addons-shallow-compare

Internal dependencies (will break in 16):

  • react/lib/shallowCompare

Plan for 15.5: copy internal dependencies into the package to make sure it works standalone. Ensure there is a UMD build in the standalone package, and that it is documented in package's README. Make sure that accessing it via React.addons.shallowCompare (but not via the package) warns once and suggests using UMD build instead. Release 15.5 without a peer dependency restriction on react and forget about it forever.

Plan for 16: we won’t be releasing 16 for this package. Nevertheless version 15 should keep working indefinitely.

react-addons-update

Internal dependencies (will break in 16):

  • react/lib/update

Plan for 15.5: copy internal dependencies into the package to make sure it works standalone. Ensure there is a UMD build in the standalone package, and that it is documented in package's README. Make sure that accessing it via React.addons.update (but not via the package) warns once and suggests using UMD build instead. Release 15.5 without a peer dependency restriction on react and forget about it forever. In README, mention https://github.com/kolodny/immutability-helper as a more maintained alternative.

Plan for 16: we won’t be releasing 16 for this package. Nevertheless version 15 should keep working indefinitely.

react-linked-input

Internal dependencies (will break in 16):

  • react/lib/LinkedValueUtils

Plan for 15.5: copy internal dependencies into the package to make sure it works standalone. Release 15.5 without a peer dependency restriction on react and forget about it forever. There is no extra step for React.addons because it is not exposed there at all.

Plan for 16: we won’t be releasing 16 for this package. Nevertheless version 15 should keep working indefinitely.

Plan: Deprecate and Forget

react-addons-css-transition-group

Internal dependencies (will break in 16):

  • react/lib/ReactCSSTransitionGroup

Plan for 15.5: deprecate. We won’t maintain this further. Suggest using CSSTransitionGroup from https://github.com/reactjs/react-transition-group instead. Work with its maintainers to ensure there’s an UMD build (and instructions for it in README).

Plan for 16: we won’t be releasing 16 for this package.

react-addons-transition-group

Internal dependencies (will break in 16):

  • react/lib/ReactTransitionGroup

Plan for 15.5: deprecate. We won’t maintain this further. Suggest using TransitionGroup from https://github.com/reactjs/react-transition-group instead. Work with its maintainers to ensure there’s an UMD build (and instructions for it in README).

Plan for 16: we won’t be releasing 16 for this package.

Plan: Undecided

react-addons-test-utils

Internal dependencies (will break in 16):

  • react-dom/lib/ReactTestUtils

I don’t have a plan for this one yet. Technically it’s still going to be coupled to react-dom package. TestUtils is technically two completely different things: a thin wrapper around react-dom with some introspection, and a shallow renderer. Perhaps it would make sense to completely move TestUtils to react-dom except shallow renderer which could be published as react-shallow-renderer.

Most helpful comment

There's been a long discussion on this so I encourage you to search issues and participate in it. 👍

All 28 comments

Note to self: I've released dev tagged versions of react-addons-css-transition-group and react-addons-transition-group with no change other than updated README (1, 2) that mentions a deprecation message. When we're ready to pull the trigger on these 2 we should publish a final (non dev tag) 15.0.0 version of these 2 and then deprecate them in NPM:

npm deprecate [email protected] "This package is deprecated and will no longer work with React 16+. We recommend you use CSSTransitionGroup from 'react-transition-group' instead."

npm deprecate [email protected] "This package is deprecated and will no longer work with React 16+. We recommend you use TransitionGroup from 'react-transition-group' instead."

Also once we've verified that each of the 15.5.0 add-on releases seem correct, we should swap NPM tags for them like so:

npm dist-tag rm  [email protected] dev
npm dist-tag add [email protected] latest

Perhaps it would make sense to completely move TestUtils to react-dom except shallow renderer which could be published as react-shallow-renderer.

Make sense to me.

import TestUtils from 'react-dom/test-utils';

?

I'm a little confused. What's the status of react-addons-create-fragment, is it still considered a feature you can rely on or is it being phased out?

@syranide

Plan for 16: we won’t be releasing 16 for this package. Nevertheless version 15 should keep working indefinitely.

@gaearon: Regarding the above propsal for 15 add-ons packages (specifically for react-addons-test-utils). Here's my understanding of the proposal:

Test utils (everything but shallow renderer)

tl;dr - Move it into react-dom

* Add a new top-level 'test-utils' import (eg react-dom/test-utils) to the upcoming react-dom 15.5.0 release for ReactTestUtils. This will be the same as today's release except it will not have a createRenderer method on it.
* Add one-time-warning for people using React.addons.TestUtils or react-addons-test-utils to instead use the new react-dom/test-utils target.

Shallow renderer

tl;dr - Move it into react-test-renderer

* Add a new top-level 'shallow' import (eg react-test-renderer/shallow) to the upcoming react-test-renderer 15.5.0 release.
* Add one-time-warning for people using React.addons.TestUtils.createRenderer (or importing createRenderer from react-addons-test-utils) to instead use react-test-renderer/shallow.

Does this seem reasonable?

cc @acdlite

@syranide

What's the status of react-addons-create-fragment, is it still considered a feature you can rely on or is it being phased out?

In addition to what Ben said, in 16 and above, react-addons-create-fragment isn't really necessary because we support arrays as a return type.

In addition to what Ben said, in 16 and above, react-addons-create-fragment isn't really necessary because we support arrays as a return type.

@acdlite Ok, I assumed there was a reason for it. But I feel like it's kind of a non-answer as well as createFragment could not be used for that purpose before. With arrays-as-return-type you can have makeshift fragments by creating a component which simply renders its children yes, but that is an opaque data structure and also one that comes with a lot of overhead, so it doesn't seem like the future of "fragments" either.

My question is basically what this means for "actual" fragments and a syntax for fragments. Is it simply the addon being scrapped or does this mean React is distancing itself from the idea of fragments as well? Or what's the story here?

Not sure what you consider "actual" fragments.

Oops my finger slipped :D

To continue my above comment, why do consider arrays not "actual" fragments? Is it because they can't be keyed (without wrapping them in a composite component)?

An API for keyed fragments is a possibility, as is a a special syntax for them in JSX. In the meantime, wrapping arrays in a functional component achieves essentially the exact same thing in terms of implementation overhead (one additional fiber).

An API for keyed fragments is a possibility, as is a a special syntax for them in JSX. In the meantime, wrapping arrays in a functional component achieves essentially the exact same thing in terms of implementation overhead.

@acdlite Yep, except that it is an opaque structure. But yes, that is good enough for now (and for me at least) and answers my concern. Thanks!

Arrays aren't really good for the job as they can't be keyed and will always emit a non-keyed warning even if you don't care about it. E.g. if you're just conditionally rendering some elements and wrapping them in a DOM-element is not a possibility. If I understand you correctly the makeshift fragments you mention can obviously be keyed in this case (and improves the syntax), but will rendering an array still require all elements to be keyed to avoid the warning?

<div>Foo {cond ? ['doodle', <Count />] : null} bar</div>

Isn't very nice at all.

<div>Foo {cond ? <MyFragment>doodle<Count /></MyFragment> : null} bar</div>

This works really well if it doesn't emit a non-keyed array warning (MyFragment simply renders this.props.children as-is).

Ideally we’ll have syntax for standalone fragments, e.g.

<div>Foo {cond ? <>doodle<Count /></> : null} bar</div>

It doesn’t make sense for them to be “addons” though—fragments are a core feature. It also doesn’t make sense to have an opaque data structure for them—arrays already do everything we need, and we just need new syntax for these use cases.

It doesn’t make sense for them to be “addons” though—fragments are a core feature. It also doesn’t make sense to have an opaque data structure for them—arrays already do everything we need, and we just need new syntax for these use cases.

@gaearon Awesome, exactly what I was hoping for, thanks! FYI, my concern was because of not having seen any discussions or notes and suddenly it seemed like fragments were being labeled "fix and forget" i.e. deprecated.

Yea fair enough. We haven’t really written anything on Fiber yet because we’re still working on it, but it had first class support for fragments from the first checkins.

We need an official React way of animating a component on it's way out to unmountville. Or rather lifecycle hooks that make this a possibility.

There's been a long discussion on this so I encourage you to search issues and participate in it. 👍

Seems like everything is done here.

@gaearon is react-dom/test-utils going to be the entry point for ReactTestUtils in 16 too? If so, can we get an alpha release with that available?

@bvaughn Did you plan to include this in latest alpha? I’m not sure I fully remember what we did when.

Building locally I see for [email protected] the test-utils file is included, so it may just be a matter of publishing it.

Oh, great! I didn't know it was published. If you look at the version dropdown on unpkg, it doesn't show alpha.10, so I assumed it was unpublished.

screen shot 2017-04-22 at 4 42 49 pm

Nevermind then, thanks!

cc @mjackson, do you know why it's not showing?

Maybe it doesn’t show until somebody has requested it?
I usually just look at a URL like https://unpkg.com/react-dom@next/ which takes me to latest alpha.

I think it's a bug with unpkg. If you load https://unpkg.com/[email protected]/ it won't show up in the dropdown. But if you load the previous or next version, it shows up.

Glad you figured this out because I totally missed this note over the weekend. Sorry! 😁

@aweary We may be caching those index pages too aggressively. Thanks for the ping. I'll look into it.

@gaearon it looks like the last release for react-addons-test-utils was 15.5.1, making it out of sync with the other React packages. Is that intentional?

All addons were out of sync (each one was released a few times independently with fixes). It’s a coincidence that most lined up. We don’t plan to keep releasing them so yes, latest versions are likely going to stay latest.

Was this page helpful?
0 / 5 - 0 ratings