diff --git a/example/test/context_test.dart b/example/test/context_test.dart
new file mode 100644
index 00000000..2b7673f1
--- /dev/null
+++ b/example/test/context_test.dart
@@ -0,0 +1,18 @@
+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'));
+}
diff --git a/example/test/context_test.html b/example/test/context_test.html
new file mode 100644
index 00000000..216fde50
--- /dev/null
+++ b/example/test/context_test.html
@@ -0,0 +1,14 @@
+
+
+
+
+ context_test
+
+
+
+
+
+
+
+
+
diff --git a/example/test/react_test_components.dart b/example/test/react_test_components.dart
index d1efb9ff..2e7d6021 100644
--- a/example/test/react_test_components.dart
+++ b/example/test/react_test_components.dart
@@ -152,3 +152,41 @@ class _MainComponent extends react.Component {
}
var mainComponent = react.registerComponent(() => new _MainComponent());
+
+class _ContextComponent extends react.Component {
+ int _renderCount = 0;
+
+ @override
+ Map getChildContext() => {
+ 'foo': 'bar',
+ 'renderCount': _renderCount
+ };
+
+ @override
+ Iterable get childContextKeys => const ['foo', '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 get contextKeys => const ['foo', 'renderCount'];
+
+ render() {
+ return react.ul({},
+ 'ContextConsumerComponent.context: ',
+ context.toString(),
+ );
+ }
+}
+var contextConsumerComponent = react.registerComponent(() => new _ContextConsumerComponent());
diff --git a/js_src/dart_helpers.js b/js_src/dart_helpers.js
index 45939220..2819cef8 100644
--- a/js_src/dart_helpers.js
+++ b/js_src/dart_helpers.js
@@ -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() {
@@ -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);
@@ -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
+ // 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) {
diff --git a/lib/react.dart b/lib/react.dart
index e64b4808..5ceef3fb 100644
--- a/lib/react.dart
+++ b/lib/react.dart
@@ -10,6 +10,8 @@ import 'package:react/src/typedefs.dart';
/// Top-level ReactJS [Component class](https://facebook.github.io/react/docs/react-component.html)
/// which provides the [ReactJS Component API](https://facebook.github.io/react/docs/react-component.html#reference)
abstract class Component {
+ Map _context;
+
/// A private field that backs [props], which is exposed via getter/setter so
/// it can be overridden in strong mode.
///
@@ -37,6 +39,12 @@ abstract class Component {
/// TODO: Switch back to a plain field once this issue is fixed.
Ref _ref;
+ /// The React context map of this component, passed down from its ancestors' [getChildContext] value.
+ ///
+ /// Only keys declared in this component's [contextKeys] will be present.
+ Map get context => _context;
+ set context(Map value) => _context = value;
+
/// ReactJS [Component] props.
///
/// Related: [state]
@@ -81,13 +89,18 @@ abstract class Component {
/// Bind the value of input to [state[key]].
bind(key) => [state[key], (value) => setState({key: value})];
- initComponentInternal(props, _jsRedraw, [Ref ref, _jsThis]) {
+ initComponentInternal(props, _jsRedraw, [Ref ref, _jsThis, context]) {
this._jsRedraw = _jsRedraw;
this.ref = ref;
this._jsThis = _jsThis;
+ _initContext(context);
_initProps(props);
}
+ _initContext(context) {
+ _context = new Map.from(context ?? {});
+ }
+
_initProps(props) {
this.props = new Map.from(props);
this.nextProps = this.props;
@@ -243,6 +256,21 @@ abstract class Component {
/// See:
void componentWillUnmount() {}
+ /// Returns a Map of context to be passed to descendant components.
+ ///
+ /// Only keys present in [childContextKeys] will be used; all others will be ignored.
+ Map getChildContext() => const {};
+
+ /// The keys this component uses in its child context map (returned by [getChildContext]).
+ ///
+ /// __This method is called only once, upon component registration.__
+ Iterable get childContextKeys => const [];
+
+ /// The keys of context used by this component.
+ ///
+ /// __This method is called only once, upon component registration.__
+ Iterable get contextKeys => const [];
+
/// Invoked once before the `Component` is mounted. The return value will be used as the initial value of [state].
///
/// See:
diff --git a/lib/react.js b/lib/react.js
index 855306e4..3f26bc1a 100644
--- a/lib/react.js
+++ b/lib/react.js
@@ -4324,10 +4324,10 @@ module.exports = ReactPropTypesSecret;
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() {
@@ -4336,14 +4336,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);
@@ -4355,6 +4355,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
+ // 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) {
diff --git a/lib/react_client.dart b/lib/react_client.dart
index 30c0e561..ebe170db 100644
--- a/lib/react_client.dart
+++ b/lib/react_client.dart
@@ -178,12 +178,32 @@ dynamic _convertArgsToChildren(List childrenArgs) {
}
}
+@JS('Object.keys')
+external List _objectKeys(Object object);
+
+InteropContextValue _jsifyContext(Map context) {
+ var interopContext = new InteropContextValue();
+ context.forEach((key, value) {
+ setProperty(interopContext, key, new ReactDartContextInternal(value));
+ });
+
+ return interopContext;
+}
+
+Map _unjsifyContext(InteropContextValue interopContext) {
+ // TODO consider using `contextKeys` for this if perf of objectKeys is bad.
+ return new Map.fromIterable(_objectKeys(interopContext), value: (key) {
+ ReactDartContextInternal internal = getProperty(interopContext, key);
+ return internal.value;
+ });
+}
+
/// The static methods that proxy JS component lifecycle methods to Dart components.
final ReactDartInteropStatics _dartInteropStatics = (() {
var zone = Zone.current;
/// Wrapper for [Component.getInitialState].
- Component initComponent(ReactComponent jsThis, ReactDartComponentInternal internal, ComponentStatics componentStatics) => zone.run(() {
+ Component initComponent(ReactComponent jsThis, ReactDartComponentInternal internal, InteropContextValue context, ComponentStatics componentStatics) => zone.run(() {
void jsRedraw() {
jsThis.setState(emptyJsMap);
}
@@ -197,7 +217,7 @@ final ReactDartInteropStatics _dartInteropStatics = (() {
};
Component component = componentStatics.componentFactory()
- ..initComponentInternal(internal.props, jsRedraw, getRef, jsThis)
+ ..initComponentInternal(internal.props, jsRedraw, getRef, jsThis, _unjsifyContext(context))
..initStateInternal();
// Return the component so that the JS proxying component can store it,
@@ -205,6 +225,10 @@ final ReactDartInteropStatics _dartInteropStatics = (() {
return component;
});
+ InteropContextValue handleGetChildContext(Component component) => zone.run(() {
+ return _jsifyContext(component.getChildContext());
+ });
+
/// Wrapper for [Component.componentWillMount].
void handleComponentWillMount(Component component) => zone.run(() {
component
@@ -225,9 +249,12 @@ final ReactDartInteropStatics _dartInteropStatics = (() {
/// 1. Update [Component.props] using the value stored to [Component.nextProps]
/// in `componentWillReceiveProps`.
/// 2. Update [Component.state] by calling [Component.transferComponentState]
- void _afterPropsChange(Component component) {
+ /// 3. Update [Component.context] with the latest
+ void _afterPropsChange(Component component, InteropContextValue nextContext) {
component.props = component.nextProps; // [1]
component.transferComponentState(); // [2]
+ // [3]
+ component.context = _unjsifyContext(nextContext);
}
void _clearPrevState(Component component) {
@@ -248,7 +275,7 @@ final ReactDartInteropStatics _dartInteropStatics = (() {
}
/// Wrapper for [Component.componentWillReceiveProps].
- void handleComponentWillReceiveProps(Component component, ReactDartComponentInternal nextInternal) => zone.run(() {
+ void handleComponentWillReceiveProps(Component component, ReactDartComponentInternal nextInternal, InteropContextValue nextContext) => zone.run(() {
var nextProps = _getNextProps(component, nextInternal);
component
..nextProps = nextProps
@@ -256,14 +283,14 @@ final ReactDartInteropStatics _dartInteropStatics = (() {
});
/// Wrapper for [Component.shouldComponentUpdate].
- bool handleShouldComponentUpdate(Component component) => zone.run(() {
+ bool handleShouldComponentUpdate(Component component, InteropContextValue nextContext) => zone.run(() {
_callSetStateTransactionalCallbacks(component);
if (component.shouldComponentUpdate(component.nextProps, component.nextState)) {
return true;
} else {
// If component should not update, update props / transfer state because componentWillUpdate will not be called.
- _afterPropsChange(component);
+ _afterPropsChange(component, nextContext);
_callSetStateCallbacks(component);
// Clear out prevState after it's done being used so it's not retained
_clearPrevState(component);
@@ -272,9 +299,9 @@ final ReactDartInteropStatics _dartInteropStatics = (() {
});
/// Wrapper for [Component.componentWillUpdate].
- void handleComponentWillUpdate(Component component) => zone.run(() {
+ void handleComponentWillUpdate(Component component, InteropContextValue nextContext) => zone.run(() {
component.componentWillUpdate(component.nextProps, component.nextState);
- _afterPropsChange(component);
+ _afterPropsChange(component, nextContext);
});
/// Wrapper for [Component.componentDidUpdate].
@@ -304,6 +331,7 @@ final ReactDartInteropStatics _dartInteropStatics = (() {
return new ReactDartInteropStatics(
initComponent: allowInterop(initComponent),
+ handleGetChildContext: allowInterop(handleGetChildContext),
handleComponentWillMount: allowInterop(handleComponentWillMount),
handleComponentDidMount: allowInterop(handleComponentDidMount),
handleComponentWillReceiveProps: allowInterop(handleComponentWillReceiveProps),
@@ -318,18 +346,24 @@ final ReactDartInteropStatics _dartInteropStatics = (() {
/// Returns a new [ReactComponentFactory] which produces a new JS
/// [`ReactClass` component class](https://facebook.github.io/react/docs/top-level-api.html#react.createclass).
ReactDartComponentFactoryProxy _registerComponent(ComponentFactory componentFactory, [Iterable skipMethods = const []]) {
+ var componentInstance = componentFactory();
var componentStatics = new ComponentStatics(componentFactory);
+ var jsConfig = new JsComponentConfig(
+ childContextKeys: componentInstance.childContextKeys,
+ contextKeys: componentInstance.contextKeys,
+ );
+
/// Create the JS [`ReactClass` component class](https://facebook.github.io/react/docs/top-level-api.html#react.createclass)
/// with custom JS lifecycle methods.
var reactComponentClass = React.createClass(
- createReactDartComponentClassConfig(_dartInteropStatics, componentStatics)
- ..displayName = componentFactory().displayName
+ createReactDartComponentClassConfig(_dartInteropStatics, componentStatics, jsConfig)
+ ..displayName = componentInstance.displayName
);
// Cache default props and store them on the ReactClass so they can be used
// by ReactDartComponentFactoryProxy and externally.
- final Map defaultProps = new Map.unmodifiable(componentFactory().getDefaultProps());
+ final Map defaultProps = new Map.unmodifiable(componentInstance.getDefaultProps());
reactComponentClass.dartDefaultProps = defaultProps;
return new ReactDartComponentFactoryProxy(reactComponentClass);
diff --git a/lib/react_client/react_interop.dart b/lib/react_client/react_interop.dart
index b26188ab..10296df5 100644
--- a/lib/react_client/react_interop.dart
+++ b/lib/react_client/react_interop.dart
@@ -83,6 +83,8 @@ class ReactClassConfig {
Function componentWillUpdate,
Function componentDidUpdate,
Function componentWillUnmount,
+ Function getChildContext,
+ Map childContextTypes,
Function getDefaultProps,
Function getInitialState,
Function render
@@ -158,6 +160,18 @@ class ReactComponent {
// Interop internals
// ----------------------------------------------------------------------------
+/// A JavaScript interop class representing a value in a React JS `context` object.
+///
+/// Used for storing/accessing Dart [ReactDartContextInternal] objects in `context`
+/// in a way that's opaque to the JS, and avoids the need to use dart2js interceptors.
+///
+/// __For internal/advanced use only.__
+@JS()
+@anonymous
+class InteropContextValue {
+ external factory InteropContextValue();
+}
+
/// A JavaScript interop class representing a React JS `props` object.
///
/// Used for storing/accessing [ReactDartComponentInternal] objects in
@@ -178,8 +192,7 @@ class InteropProps {
external factory InteropProps({ReactDartComponentInternal internal, String key, dynamic ref});
}
-/// Internal react-dart information used to proxy React JS lifecycle to Dart
-/// [Component] instances.
+/// A Dart object that stores .
///
/// __For internal/advanced use only.__
class ReactDartComponentInternal {
@@ -190,6 +203,16 @@ class ReactDartComponentInternal {
Map props;
}
+/// Internal react-dart information used to proxy React JS lifecycle to Dart
+/// [Component] instances.
+///
+/// __For internal/advanced use only.__
+class ReactDartContextInternal {
+ final dynamic value;
+
+ ReactDartContextInternal(this.value);
+}
+
/// Marks [child] as validated, as if it were passed into [React.createElement]
/// as a variadic child.
///
@@ -213,14 +236,20 @@ void markChildrenValidated(List children) {
/// [dartInteropStatics] and [componentStatics] internally to proxy between
/// the JS and Dart component instances.
@JS('_createReactDartComponentClassConfig')
-external ReactClassConfig createReactDartComponentClassConfig(ReactDartInteropStatics dartInteropStatics, ComponentStatics componentStatics);
-
-typedef Component _InitComponent(ReactComponent jsThis, ReactDartComponentInternal internal, ComponentStatics componentStatics);
+external ReactClassConfig createReactDartComponentClassConfig(
+ ReactDartInteropStatics dartInteropStatics,
+ ComponentStatics componentStatics,
+ [JsComponentConfig jsConfig]
+);
+
+typedef Component _InitComponent(ReactComponent jsThis, ReactDartComponentInternal internal, InteropContextValue context, ComponentStatics componentStatics);
+typedef InteropContextValue _HandleGetChildContext(Component component);
typedef void _HandleComponentWillMount(Component component);
typedef void _HandleComponentDidMount(Component component);
-typedef void _HandleComponentWillReceiveProps(Component component, ReactDartComponentInternal nextInternal);
-typedef bool _HandleShouldComponentUpdate(Component component);
-typedef void _HandleComponentWillUpdate(Component component);
+typedef void _HandleComponentWillReceiveProps(Component component, ReactDartComponentInternal nextInternal, InteropContextValue nextContext);
+typedef bool _HandleShouldComponentUpdate(Component component, InteropContextValue nextContext);
+typedef void _HandleComponentWillUpdate(Component component, InteropContextValue nextContext);
+// Ignore prevContext in componentDidUpdate, since it's not supported in React 16
typedef void _HandleComponentDidUpdate(Component component, ReactDartComponentInternal prevInternal);
typedef void _HandleComponentWillUnmount(Component component);
typedef dynamic _HandleRender(Component component);
@@ -231,6 +260,7 @@ typedef dynamic _HandleRender(Component component);
class ReactDartInteropStatics {
external factory ReactDartInteropStatics({
_InitComponent initComponent,
+ _HandleGetChildContext handleGetChildContext,
_HandleComponentWillMount handleComponentWillMount,
_HandleComponentDidMount handleComponentDidMount,
_HandleComponentWillReceiveProps handleComponentWillReceiveProps,
@@ -253,3 +283,14 @@ class ComponentStatics {
ComponentStatics(this.componentFactory);
}
+
+/// Additional configuration passed to [createReactDartComponentClassConfig]
+/// that needs to be directly accessible by that JS code.
+@JS()
+@anonymous
+class JsComponentConfig {
+ external factory JsComponentConfig({
+ Iterable childContextKeys,
+ Iterable contextKeys,
+ });
+}
diff --git a/lib/react_prod.js b/lib/react_prod.js
index 2ce98061..718358c7 100644
--- a/lib/react_prod.js
+++ b/lib/react_prod.js
@@ -16,10 +16,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() {
@@ -28,14 +28,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);
@@ -47,6 +47,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
+ // 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) {
diff --git a/lib/react_with_addons.js b/lib/react_with_addons.js
index ef122fab..46e5cc6f 100644
--- a/lib/react_with_addons.js
+++ b/lib/react_with_addons.js
@@ -5965,10 +5965,10 @@ module.exports = ReactPropTypesSecret;
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() {
@@ -5977,14 +5977,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);
@@ -5996,6 +5996,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
+ // 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) {
diff --git a/lib/react_with_react_dom_prod.js b/lib/react_with_react_dom_prod.js
index 82e9ddd3..b2fbb6bc 100644
--- a/lib/react_with_react_dom_prod.js
+++ b/lib/react_with_react_dom_prod.js
@@ -16,10 +16,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() {
@@ -28,14 +28,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);
@@ -47,6 +47,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
+ // 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) {