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

Context support #135

Merged
merged 32 commits into from
Dec 14, 2017
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d2e4beb
Port over initial stab at context
greglittlefield-wf Oct 26, 2017
3ec9436
Fix breaking change to initComponentInternal
greglittlefield-wf Oct 26, 2017
e1a44b0
Use internal pattern for individual context keys
greglittlefield-wf Oct 27, 2017
27fea39
Fix JS, conditionally declare context pieces on config
greglittlefield-wf Oct 27, 2017
2408a09
Generate JS files
greglittlefield-wf Oct 27, 2017
f772419
Cleanup, naming, docs
greglittlefield-wf Oct 27, 2017
bb04f63
Ignore prevContext since it isn't supported in React 16
greglittlefield-wf Oct 27, 2017
b80ac0a
Generate JS
greglittlefield-wf Oct 27, 2017
bb0bc6c
Rename to handleGetChildContext
greglittlefield-wf Oct 27, 2017
9989c2e
Add prev/nextContext and update docs
johnbland-wf Oct 27, 2017
2e7d74b
Added logging to js build
johnbland-wf Oct 27, 2017
f605e0d
Added lifecycle call checks to LifecycleTest
johnbland-wf Oct 27, 2017
88bb52f
Fix errors in react_test examples
johnbland-wf Oct 27, 2017
b410e62
Fix errors in ref_test examples
johnbland-wf Oct 27, 2017
a8585e8
Fix errors in speed_test examples
johnbland-wf Oct 27, 2017
2fba623
Fix errors in get_dom_node_test examples
johnbland-wf Oct 27, 2017
cd9ddaf
Adjust context component to test childContextKeys
johnbland-wf Oct 27, 2017
846c0f1
Update dart_helpers comment
johnbland-wf Nov 2, 2017
987b995
Merge branch 'master' of github.com:cleandart/react-dart into context
johnbland-wf Nov 30, 2017
6e31305
Clean-up / Removed componentDidUpdateWithContext
johnbland-wf Nov 30, 2017
61c6609
Added testing steps to README
johnbland-wf Nov 30, 2017
7861c20
Update example to showcase state updates
johnbland-wf Dec 1, 2017
804ac5e
Use context directly vs transferring context
johnbland-wf Dec 1, 2017
64fbaae
Add JS build to README
johnbland-wf Dec 1, 2017
5f4d403
recieves -> receives
johnbland-wf Dec 1, 2017
dc0e5af
Updated example component to show context updates to grandchildren
johnbland-wf Dec 1, 2017
92fbc53
Fix lifecycle calls and add test coverage
johnbland-wf Dec 1, 2017
723caa5
Remove forced context update
johnbland-wf Dec 5, 2017
f791d0d
Documentation updates
johnbland-wf Dec 5, 2017
f0d8b3a
Use nextContext vs unjsify’ing it
johnbland-wf Dec 5, 2017
282914b
Test updates
johnbland-wf Dec 5, 2017
3602963
Remove context test methods in JS
johnbland-wf Dec 5, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions example/test/context_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'dart:html';

import 'package:react/react_dom.dart' as react_dom;
import 'package:react/react_client.dart';

import 'react_test_components.dart';

void main() {
setClientConfiguration();

react_dom.render(contextComponent({},
contextConsumerComponent({}),
), querySelector('#content'));

react_dom.render(contextComponent({},
contextConsumerComponent({}),
), querySelector('#content'));

react_dom.render(contextComponent({},
contextConsumerComponent({}, fooOnlyContextConsumerComponent({})),
), querySelector('#content'));
}
14 changes: 14 additions & 0 deletions example/test/context_test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>

<html>
<head>
<title>context_test</title>
</head>
<body>
<div id="content"></div>
<script src="packages/react/react.js"></script>
<script src="packages/react/react_dom.js"></script>
<script type="application/dart" src="context_test.dart"></script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
14 changes: 7 additions & 7 deletions example/test/get_dom_node_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class _ChildComponent extends react.Component {
react.div({}, [
"Test element",
counter.toString(),
react.button({"onClick": (_) { counter++;redraw();} }, "Increase counter")
react.button({'key': 'button', "onClick": (_) { counter++;redraw();} }, "Increase counter")
]);
}

Expand All @@ -40,12 +40,12 @@ class SimpleComponent extends react.Component {

render() =>
react.div({}, [
react.span({"ref": "refToSpan"}, "Test"),
react.span({}, counter),
react.button({"onClick": (_) => (react_dom.findDOMNode(this) as HtmlElement).children.first.text = (++counter).toString()},"Increase counter"),
react.br({}),
ChildComponent({"ref": "refToElement"}),
react.button({"onClick": (_) => window.alert((this.ref('refToElement') as _ChildComponent).counter.toString())}, "Show value of child element"),
react.span({'key': 'span1', "ref": "refToSpan"}, "Test"),
react.span({'key': 'span2'}, counter),
react.button({'key': 'button1', "onClick": (_) => (react_dom.findDOMNode(this) as HtmlElement).children.first.text = (++counter).toString()},"Increase counter"),
react.br({'key': 'br'}),
ChildComponent({'key': 'child', "ref": "refToElement"}),
react.button({'key': 'button2', "onClick": (_) => window.alert((this.ref('refToElement') as _ChildComponent).counter.toString())}, "Show value of child element"),
]);
}

Expand Down
6 changes: 3 additions & 3 deletions example/test/react_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import "react_test_components.dart";
void main() {
setClientConfiguration();
react_dom.render(mainComponent({}, [
helloGreeter({}, []),
listComponent({}, []),
helloGreeter({'key': 'hello'}, []),
listComponent({'key': 'list'}, []),
//clockComponent({"name": 'my-clock'}, []),
checkBoxComponent({}, [])
checkBoxComponent({'key': 'checkbox'}, [])
]
), querySelector('#content'));
}
64 changes: 58 additions & 6 deletions example/test/react_test_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ class _HelloGreeter extends react.Component {

render() {
return react.div({}, [
react.input({'ref': 'myInput', 'value': bind('name'), 'onChange': onInputChange}),
helloComponent({'name': state['name']})
react.input({'key': 'input', 'ref': 'myInput', 'value': bind('name'), 'onChange': onInputChange}),
helloComponent({'key': 'hello', 'name': state['name']})
]);
}
}
Expand All @@ -47,8 +47,8 @@ class _CheckBoxComponent extends react.Component {

render() {
return react.div({}, [
react.label({'className': this.state["checked"] ? 'striked' : 'not-striked'}, 'do the dishes'),
react.input({'type': 'checkbox', 'value': bind('checked')}, [])
react.label({'key': 'label', 'className': this.state["checked"] ? 'striked' : 'not-striked'}, 'do the dishes'),
react.input({'key': 'input', 'type': 'checkbox', 'value': bind('checked')})
]);
}
}
Expand Down Expand Up @@ -136,8 +136,8 @@ class _ListComponent extends react.Component {
}

return react.div({}, [
react.button({"onClick": addItem}, "addItem"),
react.ul({}, items),
react.button({"onClick": addItem, 'key': 'button'}, "addItem"),
react.ul({'key': 'list'}, items),
]);
}
}
Expand All @@ -152,3 +152,55 @@ class _MainComponent extends react.Component {
}

var mainComponent = react.registerComponent(() => new _MainComponent());

class _ContextComponent extends react.Component {
int _renderCount = 0;

@override
Map<String, dynamic> getChildContext() => {
'foo': {'object': 'with value'},
'bar': true,
'renderCount': _renderCount
};

@override
Iterable<String> get childContextKeys => const ['foo', 'bar', 'renderCount'];

render() {
_renderCount++;

return react.ul({},
'ContextComponent.getChildContext(): ',
getChildContext().toString(),
props['children']
);
}
}
var contextComponent = react.registerComponent(() => new _ContextComponent());

class _ContextConsumerComponent extends react.Component {
@override
Iterable<String> get contextKeys => const ['foo', 'renderCount'];

render() {
return react.ul({},
'ContextConsumerComponent.context: ',
context.toString(),
props['children']
);
}
}
var contextConsumerComponent = react.registerComponent(() => new _ContextConsumerComponent());

class _FooOnlyContextConsumerComponent extends react.Component {
@override
Iterable<String> get contextKeys => const ['foo'];

render() {
return react.ul({},
'FooOnlyContextConsumerComponent.context: ',
context.toString(),
);
}
}
var fooOnlyContextConsumerComponent = react.registerComponent(() => new _FooOnlyContextConsumerComponent());
32 changes: 16 additions & 16 deletions example/test/ref_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,23 @@ class _ParentComponent extends react.Component {

render() =>
react.div({},[
react.h1({}, "String refs"),
react.h4({}, "<input>"),
react.input({"ref": "inputRef"}),
react.button({"onClick": showInputValue}, "Print input element value"),
react.h4({}, "ChildComponent"),
ChildComponent({"ref": "childRef"}),
react.button({"onClick": showChildValue}, "Print child value"),
react.button({"onClick": incrementChildValue}, "Increment child value"),
react.h1({'key': 'string-h1'}, "String refs"),
react.h4({'key': 'string-h4'}, "<input>"),
react.input({'key': 'string-input', "ref": "inputRef"}),
react.button({'key': 'string-show-input', "onClick": showInputValue}, "Print input element value"),
react.h4({'key': 'string-h4-child'}, "ChildComponent"),
ChildComponent({'key': 'string-child', "ref": "childRef"}),
react.button({'key': 'string-show-button', "onClick": showChildValue}, "Print child value"),
react.button({'key': 'string-increment-button', "onClick": incrementChildValue}, "Increment child value"),

react.h1({}, "Callback refs"),
react.h4({}, "<input>"),
react.input({"ref": (instance) => _inputCallbackRef = instance}),
react.button({"onClick": showInputCallbackRefValue}, "Print input element value"),
react.h4({}, "ChildComponent"),
ChildComponent({"ref": (instance) => _childCallbackRef = instance}),
react.button({"onClick": showChildCallbackRefValue}, "Print child value"),
react.button({"onClick": incrementChildCallbackRefValue}, "Increment child value"),
react.h1({'key': 'h1-callback'}, "Callback refs"),
react.h4({'key': 'h4-callback-input'}, "<input>"),
react.input({'key': 'callback-input', "ref": (instance) => _inputCallbackRef = instance}),
react.button({'key': 'callback-show-input', "onClick": showInputCallbackRefValue}, "Print input element value"),
react.h4({'key': 'callback-child-h4'}, "ChildComponent"),
ChildComponent({'key': 'callback-child', "ref": (instance) => _childCallbackRef = instance}),
react.button({'key': 'callback-show-button', "onClick": showChildCallbackRefValue}, "Print child value"),
react.button({'key': 'callback-increment-button', "onClick": incrementChildCallbackRefValue}, "Increment child value"),
]);
}

Expand Down
4 changes: 2 additions & 2 deletions example/test/speed_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ class _Hello extends react.Component {
for(var elem in data){
children.add(
react.div({'key': elem[0]},[
react.span({}, elem[0]),
react.span({'key': 'span1'}, elem[0]),
" ",
react.span({}, elem[1])
react.span({'key': 'span2'}, elem[1])
])
);
}
Expand Down
46 changes: 37 additions & 9 deletions js_src/dart_helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
function _getProperty(obj, key) { return obj[key]; }
function _setProperty(obj, key, value) { return obj[key] = value; }

function _createReactDartComponentClassConfig(dartInteropStatics, componentStatics) {
return {
function _createReactDartComponentClassConfig(dartInteropStatics, componentStatics, jsConfig) {
var config = {
getInitialState: function() {
this.dartComponent = dartInteropStatics.initComponent(this, this.props.internal, componentStatics);
this.dartComponent = dartInteropStatics.initComponent(this, this.props.internal, this.context, componentStatics);
return {};
},
componentWillMount: function() {
Expand All @@ -17,14 +17,14 @@ function _createReactDartComponentClassConfig(dartInteropStatics, componentStati
componentDidMount: function() {
dartInteropStatics.handleComponentDidMount(this.dartComponent);
},
componentWillReceiveProps: function(nextProps) {
dartInteropStatics.handleComponentWillReceiveProps(this.dartComponent, nextProps.internal);
componentWillReceiveProps: function(nextProps, nextContext) {
dartInteropStatics.handleComponentWillReceiveProps(this.dartComponent, nextProps.internal, nextContext);
},
shouldComponentUpdate: function(nextProps, nextState) {
return dartInteropStatics.handleShouldComponentUpdate(this.dartComponent);
shouldComponentUpdate: function(nextProps, nextState, nextContext) {
return dartInteropStatics.handleShouldComponentUpdate(this.dartComponent, nextContext);
},
componentWillUpdate: function(nextProps, nextState) {
dartInteropStatics.handleComponentWillUpdate(this.dartComponent);
componentWillUpdate: function(nextProps, nextState, nextContext) {
dartInteropStatics.handleComponentWillUpdate(this.dartComponent, nextContext);
},
componentDidUpdate: function(prevProps, prevState) {
dartInteropStatics.handleComponentDidUpdate(this.dartComponent, prevProps.internal);
Expand All @@ -36,6 +36,34 @@ function _createReactDartComponentClassConfig(dartInteropStatics, componentStati
return dartInteropStatics.handleRender(this.dartComponent);
}
};

// React limits the accessible context entries
// to the keys specified in childContextTypes/contextTypes.

var childContextKeys = jsConfig && jsConfig.childContextKeys;
var contextKeys = jsConfig && jsConfig.contextKeys;

if (childContextKeys && childContextKeys.length !== 0) {
config.childContextTypes = {};
for (var i = 0; i < childContextKeys.length; i++) {
config.childContextTypes[childContextKeys[i]] = React.PropTypes.object;
}

// Only declare this when `hasChildContext` is true to avoid unnecessarily

Choose a reason for hiding this comment

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

Referencing an old variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Possibly. I'll dig into it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think so, sorry about that. Should probably read when childContextKeys is non-empty

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

// creating interop context objects for components that won't use it.
config.getChildContext = function() {
return dartInteropStatics.handleGetChildContext(this.dartComponent);
};
}

if (contextKeys && contextKeys.length !== 0) {
config.contextTypes = {};
for (var i = 0; i < contextKeys.length; i++) {
config.contextTypes[contextKeys[i]] = React.PropTypes.object;
}
}

return config;
}

function _markChildValidated(child) {
Expand Down
Loading