Pass context to the constructor

This should reenable reading this.context from getInitialState.

Added a bunch of tests for this too.
This commit is contained in:
Sebastian Markbage
2015-01-23 10:09:45 -08:00
parent 766a79c695
commit 9abd1133c9
5 changed files with 66 additions and 3 deletions
+2 -1
View File
@@ -805,7 +805,7 @@ var ReactClass = {
* @public
*/
createClass: function(spec) {
var Constructor = function(props) {
var Constructor = function(props, context) {
// This constructor is overridden by mocks. The argument is used
// by mocks to assert on what gets mounted.
@@ -815,6 +815,7 @@ var ReactClass = {
}
this.props = props;
this.context = context;
this.state = null;
// ReactClasses doesn't have constructors. Instead, they use the
@@ -278,6 +278,36 @@ describe('ReactClass-spec', function() {
expect(instance.state.occupation).toEqual('clown');
});
it('renders based on context getInitialState', function() {
var Foo = React.createClass({
contextTypes: {
className: React.PropTypes.string
},
getInitialState() {
return { className: this.context.className };
},
render() {
return <span className={this.state.className} />;
}
});
var Outer = React.createClass({
childContextTypes: {
className: React.PropTypes.string
},
getChildContext() {
return { className: 'foo' };
},
render() {
return <Foo />;
}
});
var container = document.createElement('div');
React.render(<Outer />, container);
expect(container.firstChild.className).toBe('foo');
});
it('should throw with non-object getInitialState() return values', function() {
[['an array'], 'a string', 1234].forEach(function(state) {
var Component = React.createClass({
+1 -1
View File
@@ -169,7 +169,7 @@ var ReactCompositeComponentMixin = assign({},
);
// Initialize the public class
var inst = new Component(publicProps);
var inst = new Component(publicProps, publicContext);
// These should be set up in the constructor, but as a convenience for
// simpler class abstractions, we set them up after the fact.
inst.props = publicProps;
+2 -1
View File
@@ -19,8 +19,9 @@ var warning = require('warning');
/**
* Base class helpers for the updating state of a component.
*/
function ReactComponentBase(props) {
function ReactComponentBase(props, context) {
this.props = props;
this.context = context;
}
/**
@@ -98,6 +98,37 @@ describe('ReactES6Class', function() {
test(<Foo />, 'SPAN', 'bar');
});
it('renders based on context in the constructor', function() {
class Foo extends React.Component {
constructor(props, context) {
super(props, context);
this.state = { tag: context.tag, className: this.context.className };
}
render() {
var Tag = this.state.tag;
return <Tag className={this.state.className} />;
}
}
Foo.contextTypes = {
tag: React.PropTypes.string,
className: React.PropTypes.string
};
class Outer extends React.Component {
getChildContext() {
return { tag: 'span', className: 'foo' };
}
render() {
return <Foo />;
}
}
Outer.childContextTypes = {
tag: React.PropTypes.string,
className: React.PropTypes.string
};
test(<Outer />, 'SPAN', 'foo');
});
it('renders only once when setting state in componentWillMount', function() {
var renderCount = 0;
class Foo extends React.Component {