Skip to content

Commit 4ba8269

Browse files
committed
Fix context getting
1 parent a98e822 commit 4ba8269

File tree

2 files changed

+91
-6
lines changed

2 files changed

+91
-6
lines changed

src/addons/__tests__/renderSubtreeIntoContainer-test.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,86 @@ describe('renderSubtreeIntoContainer', () => {
215215
expect(portal.firstChild.innerHTML).toBe('hello');
216216
});
217217

218+
it('should get context through non-context-provider parent', () => {
219+
var container = document.createElement('div');
220+
document.body.appendChild(container);
221+
var portal = document.createElement('div');
222+
223+
class Parent extends React.Component {
224+
render() {
225+
return <Middle />;
226+
}
227+
getChildContext() {
228+
return {value: this.props.value};
229+
}
230+
static childContextTypes = {
231+
value: React.PropTypes.string.isRequired,
232+
};
233+
}
234+
235+
class Middle extends React.Component {
236+
render() {
237+
return null;
238+
}
239+
componentDidMount() {
240+
renderSubtreeIntoContainer(this, <Child />, portal);
241+
}
242+
}
243+
244+
class Child extends React.Component {
245+
static contextTypes = {
246+
value: React.PropTypes.string.isRequired,
247+
};
248+
render() {
249+
return <div>{this.context.value}</div>;
250+
}
251+
}
252+
253+
ReactDOM.render(<Parent value="foo" />, container);
254+
expect(portal.textContent).toBe('foo');
255+
});
256+
257+
it('should get context through middle non-context-provider layer', () => {
258+
var container = document.createElement('div');
259+
document.body.appendChild(container);
260+
var portal1 = document.createElement('div');
261+
var portal2 = document.createElement('div');
262+
263+
class Parent extends React.Component {
264+
render() {
265+
return null;
266+
}
267+
getChildContext() {
268+
return {value: this.props.value};
269+
}
270+
componentDidMount() {
271+
renderSubtreeIntoContainer(this, <Middle />, portal1);
272+
}
273+
static childContextTypes = {
274+
value: React.PropTypes.string.isRequired,
275+
};
276+
}
277+
278+
class Middle extends React.Component {
279+
render() {
280+
return null;
281+
}
282+
componentDidMount() {
283+
renderSubtreeIntoContainer(this, <Child />, portal2);
284+
}
285+
}
286+
287+
class Child extends React.Component {
288+
static contextTypes = {
289+
value: React.PropTypes.string.isRequired,
290+
};
291+
render() {
292+
return <div>{this.context.value}</div>;
293+
}
294+
}
295+
296+
ReactDOM.render(<Parent value="foo" />, container);
297+
expect(portal2.textContent).toBe('foo');
298+
});
299+
218300
});

src/renderers/shared/fiber/ReactFiberContext.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ var {
2222
} = require('ReactFiberTreeReflection');
2323
var {
2424
ClassComponent,
25+
HostContainer,
2526
} = require('ReactTypeOfWork');
2627

2728
if (__DEV__) {
@@ -137,12 +138,14 @@ exports.findCurrentUnmaskedContext = function(fiber: Fiber) : Object {
137138
'Expected subtree parent to be a mounted class component'
138139
);
139140

140-
let node : ?Fiber = parent;
141-
while (node) {
142-
if (isContextProvider(fiber)) {
143-
return fiber.stateNode.__reactInternalMemoizedMergedChildContext;
141+
let node : Fiber = fiber;
142+
while (node.tag !== HostContainer) {
143+
if (isContextProvider(node)) {
144+
return node.stateNode.__reactInternalMemoizedMergedChildContext;
144145
}
145-
node = node.return;
146+
const parent = node.return;
147+
invariant(parent, 'Found unexpected detached subtree parent');
148+
node = parent;
146149
}
147-
return emptyObject;
150+
return node.stateNode.context;
148151
};

0 commit comments

Comments
 (0)