Skip to content

Commit

Permalink
Redraw only once when store triggers along with ancestor rerender
Browse files Browse the repository at this point in the history
  • Loading branch information
greglittlefield-wf committed Aug 8, 2017
1 parent a341ce8 commit af7e043
Showing 4 changed files with 86 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lib/src/component_declaration/flux_component.dart
Original file line number Diff line number Diff line change
@@ -175,6 +175,11 @@ abstract class _FluxComponentMixin<TProps extends FluxUiProps> implements Batche
});
}

void componentDidUpdate(Map prevProps, Map prevState) {
// Let BatchedRedraws know that this component has redrawn in the current batch
didBatchRedraw = true;
}

void componentWillUnmount() {
// Ensure that unmounted components don't batch render
shouldBatchRedraw = false;
8 changes: 8 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -37,3 +37,11 @@ transformers:
$include: test/**_test{.*,}.dart
# Reminder: dart2js should come after any other transformers that touch Dart code
- $dart2js


dependency_overrides:
w_flux:
git:
url: git@github.com:greglittlefield-wf/w_flux.git
ref: 189a1f97d95e0e3c446a5192c54e890fa61ebfb4 # from multiple_flux_redraws

46 changes: 46 additions & 0 deletions test/over_react/component_declaration/flux_component_test.dart
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ import '../../test_util/test_util.dart';

part 'flux_component_test/default.dart';
part 'flux_component_test/handler_precedence.dart';
part 'flux_component_test/nested.dart';
part 'flux_component_test/redraw_on.dart';
part 'flux_component_test/store_handlers.dart';

@@ -164,6 +165,51 @@ void main() {
await nextTick();
expect(component.numberOfRedraws, equals(0));
});

test('only redraws once in response to a store trigger combined with an ancestor rerendering', () async {
var store = new Store();

TestNestedComponent nested0;
TestNestedComponent nested1;
TestNestedComponent nested2;

render(
(TestNested()
..store = store
..ref = (ref) { nested0 = ref; }
)(
(TestNested()
..store = store
..ref = (ref) { nested1 = ref; }
)(
(TestNested()
..store = store
..ref = (ref) { nested2 = ref; }
)()
)
)
);
expect(nested0.renderCount, 1, reason: 'setup check: initial render');
expect(nested1.renderCount, 1, reason: 'setup check: initial render');
expect(nested2.renderCount, 1, reason: 'setup check: initial render');

nested0.redraw();
await nextTick();

expect(nested0.renderCount, 2, reason: 'setup check: components should rerender their children');
expect(nested1.renderCount, 2, reason: 'setup check: components should rerender their children');
expect(nested2.renderCount, 2, reason: 'setup check: components should rerender their children');

store.trigger();
// Two async gaps just to be safe, since we're
// asserting that additional redraws don't happen.
await nextTick();
await nextTick();

expect(nested0.renderCount, 3, reason: 'should have rerendered once in response to the store triggering');
expect(nested1.renderCount, 3, reason: 'should have rerendered once in response to the store triggering');
expect(nested2.renderCount, 3, reason: 'should have rerendered once in response to the store triggering');
});
});
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
part of over_react.component_declaration.flux_component_test;

@Factory()
UiFactory<TestNestedProps> TestNested;

@Props()
class TestNestedProps extends FluxUiProps {}

@Component()
class TestNestedComponent extends FluxUiComponent {
int renderCount = 0;

@override
render() {
renderCount++;

var keyCounter = 0;
var newChildren = props.children.map((child) {
// The keys are consistent across rerenders, so they aren't remounted,
// but cloning the element is necessary for react to consider it changed,
// since it returns new ReactElement instances.
return cloneElement(child, domProps()..key = keyCounter++);
}).toList();

return Dom.div()(newChildren);
}
}

0 comments on commit af7e043

Please sign in to comment.