Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v5 release chores #473

Closed
7 tasks done
jimbolla opened this issue Aug 27, 2016 · 40 comments
Closed
7 tasks done

v5 release chores #473

jimbolla opened this issue Aug 27, 2016 · 40 comments
Labels
Milestone

Comments

@jimbolla
Copy link
Contributor

jimbolla commented Aug 27, 2016

Starting a list of things related getting v5 out the door.

  • Unhide new features - currently they are hidden so that nobody starts using them, just in case we roll this back. I'll make a PR (exposes new features to the API #474) that will unhide them that can be merged in once we're confident that these changes will go live.
  • Create release notes - needs to describe: still API compatible, synopsis of internal architectural changes, perf changes, bugs fixed, new features added
  • Review/revise release notes @timdorr toughts?
  • Write documentation for new features. Need to adequately describe connectAdvanced, as well as new options passable to connect. PR Update API docs for v5 #480
  • Review/revise new docs. @timdorr @markerikson toughts?
  • Fix controlled input issues Connected text input cursor position reset on input #525
  • Release another beta with the new features exposed. Add beta to the github Releases page.

Nice to Haves:

  • Refactor tests? - now that connect is split into to conceptual pieces: connectAdvanced for store subscription and component lifecycle stuff vs connect's selector functions, many of the tests could be refactored to deal with just one or the other. This would be nice because would split the 2000+ line spec file in two, making it a little easier to work with. Also add new tests for some of the new connect options. (I personally need to learn how to run the new test coverage tools so I can see what's not covered.)
@timdorr
Copy link
Member

timdorr commented Aug 27, 2016

I already updated the code linting (#461), so that's taken care of. I intentionally didn't use airbnb because I didn't want to change styles just for the sake of changing styles.

Flow and Typescript typings both have PRs open (#389 and #433) respectively. They have atrophied, but I'm not a user of either typing system, so I can't really champion either effort. That has to come from the community.

@timdorr
Copy link
Member

timdorr commented Aug 27, 2016

If you want to update the API.md with some initial changes or documentation placeholders, I can collaborate with you on that to put it over the finish line. That's really the key thing needed to get to 5.0.0 final.

@jimbolla
Copy link
Contributor Author

react-redux v5 release notes (WIP)

TL;DR

  • Backwards compatible API
  • Major internal changes
  • Significant performance improvements in common usage patterns
  • Bugs fixed
  • Additional features added to connect()
  • New connectAdvanced() API

API Compatibility

Version 5.0 maintains API compatibility with v4.x but due to major internal changes, we felt a major version bump was warranted. Store state change notifications sent to components are now guaranteed to occur top-down, so if your code may behave differently if it relied on notifications happening out of order.

Internal Changes

Internally, the code for connect has been rewritten from the ground-up to be more modular, with the intention of greater maintainability and extensibility. This has also led to some new features and performance improvements.

Performance improvements

Significant performance gains were achieved by avoiding extra calls to setState() and render() by ensuring the order of change notifications to occur top-down, matching React's natural flow. Performance tests and benchmarks are discussed in #416.

Bugfixes

Some bugs/issues are resolved, related to performance loss and also impure components not re-rendering.

New features added to connect()

The behavior of connect() is now more customizable, by passing additional properties in the options arg. These will be described in the API docs.

New top level API: connectAdvanced()

The new implementation of connect() splits its behavior such that it is now a wrapper around a more-generalized connectAdvanced(). This connectAdvanced() method can be called directly if you have extreme performance needs or want to craft an API different than that of connect(). This will be described in the API docs.

@jimbolla
Copy link
Contributor Author

There's a start for the release notes. I'll start on the api.md and submit that as another PR once I have something substantial.

@markerikson
Copy link
Contributor

It'd be nice to get the API docs more "official"-looking. At the moment, they're just buried in the repo, which is not terribly obvious. Can we Gitbook-ify them, publish them, and also add a pointer from the Redux docs to the React-Redux docs?

@jimbolla
Copy link
Contributor Author

I'm unfamiliar with Gitbook... what does that conversion entail?

@timdorr
Copy link
Member

timdorr commented Aug 27, 2016

I think we can just reorganize the Readme a bit. A gitbook isn't really needed for only a couple pages of docs. The main Redux docs cover usage info for this repo anyways. We're better off leaving this one to just the basics.

@markerikson
Copy link
Contributor

Okay. Can we at least stick some specific shorter "manual" <a> tags in there, so that it's possible to link directly to one of the API descriptions without having a hash anchor that's longer than the API description? :)

@jimbolla
Copy link
Contributor Author

I started updating docs here, but ran out of time tonight.

@jimbolla
Copy link
Contributor Author

There's an ok start to the docs update in PR #480. Would love some CC.

@jimbolla
Copy link
Contributor Author

jimbolla commented Sep 9, 2016

@markerikson Can you give me an example of what to add in there for manual tags and I'll update the docs this weekend?

@timdorr Thoughts on adding the beta release to the github releases tab?

@markerikson
Copy link
Contributor

@jimbolla : You can stick HTML straight into Markdown, so what I did was insert <a> tags right before each appropriate section header. I gave each anchor a custom relevant shorter name, as opposed to the long auto-generated names from the slugified header text:

<a id="general-only-react"></a>
### Can Redux only be used with React?

@jimbolla
Copy link
Contributor Author

@markerikson I threw some a tags in PR #480

@timdorr
Copy link
Member

timdorr commented Sep 12, 2016

Sorry I've been captain lazypants on this stuff. I hope to get to some of it in the next few days (namely another beta release).

@jimbolla
Copy link
Contributor Author

@timdorr It's all good. I appreciate that everyone has their own things going on. I just want to make sure this doesn't get lost.

@timdorr
Copy link
Member

timdorr commented Oct 5, 2016

Finally pushed out beta 2: https://github.com/reactjs/react-redux/releases/tag/v5.0.0-beta.2

Sorry, I had an eventful week (lots of personal issues; check my Twitter feed), so I haven't had time for this lately :|

@timdorr
Copy link
Member

timdorr commented Oct 24, 2016

Almost there...

@timdorr timdorr added this to the 5.0 milestone Nov 8, 2016
@timdorr timdorr added the meta label Nov 8, 2016
@timdorr
Copy link
Member

timdorr commented Nov 28, 2016

All set!

I'm closing on a house on Wednesday, so can we do this at the end of the week? I can push an RC out tonight just to check any last-minute issues and prep the release notes and such.

@jimbolla
Copy link
Contributor Author

@timdorr Let me know if I can help.

@timdorr
Copy link
Member

timdorr commented Nov 29, 2016

Sorry, I got tied up with some last-minute house things last night. Will try to get to that release soon.

@jimbolla
Copy link
Contributor Author

No sweat. Enjoy your new house and new Tesla, moneybags. 😆

@timdorr
Copy link
Member

timdorr commented Dec 5, 2016

OK, obviously didn't get to this over the weekend as promised. I'll try to push something out today. Just have to prepare the release notes and we'll be good.

@ghigt
Copy link

ghigt commented Dec 7, 2016

I have a regression between the beta3 and the rc1.
Children are called before the parent after a change.
I had the same problem with the v4 but it was solved using beta3 of v5.

@jimbolla
Copy link
Contributor Author

jimbolla commented Dec 7, 2016

@ghigt we added a setting in rc1 to make it opt-in, but then removed it in latest. there isn't a release w/ the latest. see the release notes for rc1 for details.

@jimbolla
Copy link
Contributor Author

jimbolla commented Dec 7, 2016

@timdorr I think everything's good to go. Perf tests look good. The only known issue is broken HMR (#513) which I can spend some time fixing while on christmas vacation. I added a note about that to the release notes draft, which look good.

@timdorr
Copy link
Member

timdorr commented Dec 7, 2016

Moving is haaard! 😭

@gnoff
Copy link
Contributor

gnoff commented Dec 7, 2016

@timdorr Can we publish an rc2 with the expected 5.0 change?

@timdorr
Copy link
Member

timdorr commented Dec 7, 2016

I'm just going to go hardcore 5.0 whenever I have a chance. I'm moving the big stuff on Sunday (I'm doing what I can do in my car over the past week and through the weekend), so I should definitely be free by then. I keep trying to come up with time for it, but I also enjoy sleep 😜

@jimbolla
Copy link
Contributor Author

jimbolla commented Dec 7, 2016

@gnoff If you're eager to test it, I published the latest changes as @jimbolla/react-redux. You can npm install that and then if you're using webpack, you can alias that on top of react-redux proper:

{
  resolve: {
    alias: {
      'react-redux': '@jimbolla/react-redux',
    }
   }
}

@ghigt
Copy link

ghigt commented Dec 8, 2016

@jimbolla sorry, I didn't understand well the release note. As I don't have any issue with the beta3, I'll keep it until the flag is removed. Thanks for your reply.

@gaearon
Copy link
Contributor

gaearon commented Dec 10, 2016

Refactor tests? - now that connect is split into to conceptual pieces: connectAdvanced for store subscription and component lifecycle stuff vs connect's selector functions, many of the tests could be refactored to deal with just one or the other. This would be nice because would split the 2000+ line spec file in two, making it a little easier to work with.

I’d like to offer some words of caution about this one. We recently went through some pains rewriting React tests in terms of public API. We are rewriting its internals, and so unit tests for old internals turned out to be useless and sometimes complicated to port.

I’m still not sure if the top-down subscription approach will pan out long term. I haven’t thought about it really. I don’t want to be the grumpy person here and I appreciate all the effort, but relying on lifecycle order feels fragile, and reliant on React implementation details. I’m not sure this exact approach will still work with Fiber in the future. React has the batching feature for this, and it will eventually batch everything by default. Maybe we can just flip the implementation then.

In any case, I would prefer that we keep tests based around public API whenever possible. It’s fine to add more granular unit tests but any important behavior should have an integration test. Otherwise it will be tricky to change the underlying implementation later if we need to.

@markerikson
Copy link
Contributor

I admittedly only really looked through the internals the one time during the work on #416, and haven't dug through them since. But: I thought the point of the top-down subscriptions was to avoid being dependent on lifecycle ordering.

@markerikson
Copy link
Contributor

Just saw your Reddit comment at https://www.reddit.com/r/reactjs/comments/5hf4d4/an_artificial_example_where_mobx_really_shines/db09sf2/ . Quoting for posterity:

To be honest I'm still feeling wary about subscribing in order. This feels like a hack for something React can already do in the batched mode. But I'm not actively involved now so it's hard for me to say.

@jimbolla is way more familiar with the guts of this, and you're obviously way more familiar with the guts of React, but as I understand it there's two main intended benefits:

  • Ensure that we don't have children subscribing before parents, as can happen in 4.x. The current behavior results in nasty bugs if you're using the "connected parent passing IDs to connected children" pattern, as a child whose item just got deleted may try to retrieve no-longer-existing data before its parent has a chance to re-render without that child. Top-down subscriptions solve that by ensuring that the parent re-renders first, causing the child to unmount.
  • By handling things top-down, it minimizes wasted effort, since a connected child won't call setState before its parent has.

@gaearon
Copy link
Contributor

gaearon commented Dec 10, 2016

The current behavior results in nasty bugs if you're using the "connected parent passing IDs to connected children" pattern, as a child whose item just got deleted may try to retrieve no-longer-existing data before its parent has a chance to re-render without that child.

Right, but wouldn’t this problem cease to exist were all setStates batched by React and executed in the correct order in the future? I’m just trying to figure out the longer term plan.

since a connected child won't call setState before its parent has.

Longer term this shouldn't matter. (That's what batching solves.)

But: I thought the point of the top-down subscriptions was to avoid being dependent on lifecycle ordering.

It is dependent on setState callbacks which seems unfortunate to me because it forces React to keep track of them. This will negate some benefits of Fiber if I understand it correctly. I’m totally fine with doing it if it’s necessary now but I just want us to keep a larger picture in mind and have a way out of this eventually.

@markerikson
Copy link
Contributor

Right, but wouldn’t this problem cease to exist were all setStates batched by React and executed in the correct order in the future? I’m just trying to figure out the longer term plan.

Ah... as I understand it, no - it's the subscription itself that's the issue. In other words, something like:

const mapState = (state, ownProps) => {
    const itemForThisComponent = state.items[ownProps.itemID];
    const {someValue} = itemForThisComponent;
    return {someValue};
}

If you deleted the item, then when mapState tries to read out that entry and extract further data from it, itemForThisComponent is going to be undefined, and the someValue read will blow up. Sure, you can (and probably should) put in defaults and failsafes, but not everyone will. I ran into this in my own app a few times, and it took me a while to catch on to the pattern.

@jimbolla
Copy link
Contributor Author

It is dependent on setState callbacks which seems unfortunate to me because it forces React to keep track of them.

This isn't true anymore. I removed the setState callback and moved it to componentDidUpdate.

I added the top-down subscriptions to fix the stale props issue, as discussed in #292, as well as the your comments above. This ensures that mapStateToProps only gets called with fresh props.

The major perf issue in 4.5 was related to the way that the component's store listener would call setState for every store change, if the component's mapStateToProps depended on ownProps. #398 was one such report of this. The perf loss occurred even if the component ultimately didn't rerender. It seems just calling setState itself is costly enough.

My solution was to make sure the listener only has to call setState if it actually has new final props by calling mapStateToProps etc during the listener & before calling setState. So that work is now being done outside the React lifecycle. This is also what will enable us to unimplement shouldComponentUpdate, as discussed in #507.

In order to take advantage of React's batched updates, we'd have to bring the props calculate back into the React lifecycle. I haven't completely thought it through, but I believe that would involve:

  • Going back to calling setState for every store state change, but wrapping it in a call to batchedUpdates.
  • Computing new final props during componentWillUpdate
  • Preserving shouldComponentUpdate

but relying on lifecycle order feels fragile, and reliant on React implementation details.

In my opinion, this way would be more reliant on React's implementation details.

@markerikson
Copy link
Contributor

@jimbolla , side question: per your comments in dtinth/pixelpaint#1 (comment) , any other tweaks you can think of that would help improve perf in that kind of scenario? I know, I know, all programming is tradeoffs and nothing is perfect, just would be nice to say that v5 is better in every way :)

@timdorr
Copy link
Member

timdorr commented Dec 12, 2016

BTW, the hold-up on this release is me. I just did my move today and don't yet have reliable internet access (coming to you from my phone's hotspot temporarily). Once they can plug in the right wire outside my house, I can get this taken care of and welcome us to The Future™!

@timdorr
Copy link
Member

timdorr commented Dec 14, 2016

Done 💥

@timdorr timdorr closed this as completed Dec 14, 2016
@timdorr
Copy link
Member

timdorr commented Dec 14, 2016

Obligatory tweet! https://twitter.com/timdorr/status/808898559097573376

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants