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

UIP-2114: Update FluxUiComponent subscriptions when props are updated #77

Conversation

greglittlefield-wf
Copy link
Contributor

Ultimate problem:

If a FluxUiComponent is rerendered with different props.store or different props that affect the return value of redrawOn, it does not currently update its subscriptions to look at the latest store. This can happen indirectly as a result of rerendering larger views.

How it was fixed:

  • Re-bind store handlers/subscriptions whenever a component is rerendered with new props, ensuring that the latest are always referenced.
  • Add mustCallSuper annotations to help consumers detect when they're interfering with existing mount/unmount hooks, as well as the new lifecycle hooks added to support this new behavior
    • Note: If existing consumers don't call super on componentWillReceiveProps/componentDidUpdate, then they just won't get this improved behavior. However, they may hit state issues if they call super on one and not the other.
  • Add test

Testing suggestions:

  • Verify that tests pass

Potential areas of regression:

  • FluxUiComponent rerendering

FYA: @greglittlefield-wf @aaronlademann-wf @jacehensley-wf @clairesarsam-wf @joelleibow-wf

@aviary-wf
Copy link

Raven

Number of Findings: 0

@codecov-io
Copy link

codecov-io commented Jun 13, 2017

Codecov Report

Merging #77 into master will decrease coverage by 0.06%.
The diff coverage is 91.67%.

@@            Coverage Diff             @@
##           master      #77      +/-   ##
==========================================
- Coverage   97.63%   97.58%   -0.05%     
==========================================
  Files          28       28              
  Lines        1392     1402      +10     
==========================================
+ Hits         1359     1368       +9     
- Misses         33       34       +1

/// respective handlers.
void _bindStoreHandlers() {
if (_areStoreHandlersBound) {
throw new StateError('Store handlers are already bound');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@greglittlefield-wf does this need a unit test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only case this would be hit is if someone doesn't add a super-call.

I wasn't sure if it was worth adding a test around, but I can add one if you'd like.


/// Subscribe to all applicable stores.
///
/// [Store]s returned by [redrawOn] will have their triggers mapped directly to this components
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

component's

var stores = new TestStores();
var newStores = new TestStores();

var testJacket = mount<TestRedrawOnComponent>((TestRedrawOn()..store = stores)());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@override
void componentWillReceiveProps(Map prevProps) {
// Unbind store handlers so they can be re-bound in componentDidUpdate
// once the new props are available, ensuring the values returned [redrawOn]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returned by?

// Unbind store handlers so they can be re-bound in componentDidUpdate
// once the new props are available, ensuring the values returned by [redrawOn]
// are not outdated.
_unbindStoreHandlers();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth only doing this if prevProps.store != props.store?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd have to compare the equality of the return value of redrawOn and getStoreHandlers, and we don't have access to those updated values until componentDidUpdate (since those functions often rely on values within props). So, we'd have to store the old values in here and then check them and null them out in componentDidUpdate.

We can do that, but I figured that unbinding/rebinding was cheap enough that it was worth doing so to avoid that kind of comparison.

…ps_update/dev

# Conflicts:
#	lib/src/component_declaration/flux_component.dart
@aaronlademann-wf
Copy link
Contributor

QA +1

  • Testing instruction
  • Dev +1's
  • Dev/QA +10
  • Unit tests created/updated
  • All unit tests pass
  • Rosie ran/Rosie comment displays expected info
  • Dependency Scan Clean

Merging.

greglittlefield-wf added a commit that referenced this pull request Jun 15, 2017
…props_update/dev"

This reverts commit c0d2026, reversing
changes made to 4e898ff.
greglittlefield-wf added a commit that referenced this pull request Jun 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants