Skip to content

Commit 382f399

Browse files
committed
Fixed all unit tests for issue facebook#2112
1 parent 1de3859 commit 382f399

13 files changed

+217
-91
lines changed

src/browser/ReactTextComponent.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ assign(ReactTextComponent.prototype, ReactComponent.Mixin, {
5151
* @return {string} Markup for this text node.
5252
* @internal
5353
*/
54-
mountComponent: function(rootID, transaction, mountDepth) {
54+
mountComponent: function(rootID, transaction, mountDepth, context) {
5555
ReactComponent.Mixin.mountComponent.call(
5656
this,
5757
rootID,
5858
transaction,
59-
mountDepth
59+
mountDepth,
60+
context
6061
);
6162

6263
var escapedText = escapeTextForBrowser(this.props);

src/browser/server/ReactServerRendering.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@ var ReactMarkupChecksum = require('ReactMarkupChecksum');
1717
var ReactServerRenderingTransaction =
1818
require('ReactServerRenderingTransaction');
1919

20+
var emptyObject = require('emptyObject');
2021
var instantiateReactComponent = require('instantiateReactComponent');
2122
var invariant = require('invariant');
2223

2324
/**
2425
* @param {ReactElement} element
26+
* @param {?object} context
2527
* @return {string} the HTML markup
2628
*/
27-
function renderToString(element) {
29+
function renderToString(element, context) {
30+
if(context === undefined) context = emptyObject;
2831
invariant(
2932
ReactElement.isValidElement(element),
3033
'renderToString(): You must pass a valid ReactElement.'
@@ -37,7 +40,7 @@ function renderToString(element) {
3740

3841
return transaction.perform(function() {
3942
var componentInstance = instantiateReactComponent(element, null);
40-
var markup = componentInstance.mountComponent(id, transaction, 0);
43+
var markup = componentInstance.mountComponent(id, transaction, 0, context);
4144
return ReactMarkupChecksum.addChecksumToMarkup(markup);
4245
}, null);
4346
} finally {
@@ -47,10 +50,12 @@ function renderToString(element) {
4750

4851
/**
4952
* @param {ReactElement} element
53+
* @param {?object} context
5054
* @return {string} the HTML markup, without the extra React ID and checksum
5155
* (for generating static pages)
5256
*/
53-
function renderToStaticMarkup(element) {
57+
function renderToStaticMarkup(element, context) {
58+
if(context === undefined) context = emptyObject;
5459
invariant(
5560
ReactElement.isValidElement(element),
5661
'renderToStaticMarkup(): You must pass a valid ReactElement.'
@@ -63,7 +68,7 @@ function renderToStaticMarkup(element) {
6368

6469
return transaction.perform(function() {
6570
var componentInstance = instantiateReactComponent(element, null);
66-
return componentInstance.mountComponent(id, transaction, 0);
71+
return componentInstance.mountComponent(id, transaction, 0, context);
6772
}, null);
6873
} finally {
6974
ReactServerRenderingTransaction.release(transaction);

src/browser/ui/ReactDOMComponent.js

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,18 +168,20 @@ ReactDOMComponent.Mixin = {
168168
mountComponent: ReactPerf.measure(
169169
'ReactDOMComponent',
170170
'mountComponent',
171-
function(rootID, transaction, mountDepth) {
171+
function(rootID, transaction, mountDepth, context) {
172+
invariant(context !== undefined, "Context is required parameter");
172173
ReactComponent.Mixin.mountComponent.call(
173174
this,
174175
rootID,
175176
transaction,
176-
mountDepth
177+
mountDepth,
178+
context
177179
);
178180
assertValidProps(this.props);
179181
var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>';
180182
return (
181183
this._createOpenTagMarkupAndPutListeners(transaction) +
182-
this._createContentMarkup(transaction) +
184+
this._createContentMarkup(transaction, context) +
183185
closeTag
184186
);
185187
}
@@ -241,9 +243,10 @@ ReactDOMComponent.Mixin = {
241243
*
242244
* @private
243245
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
246+
* @param {object} context
244247
* @return {string} Content markup.
245248
*/
246-
_createContentMarkup: function(transaction) {
249+
_createContentMarkup: function(transaction, context) {
247250
var prefix = '';
248251
if (this._tag === 'listing' ||
249252
this._tag === 'pre' ||
@@ -269,15 +272,17 @@ ReactDOMComponent.Mixin = {
269272
} else if (childrenToUse != null) {
270273
var mountImages = this.mountChildren(
271274
childrenToUse,
272-
transaction
275+
transaction,
276+
context
273277
);
274278
return prefix + mountImages.join('');
275279
}
276280
}
277281
return prefix;
278282
},
279283

280-
receiveComponent: function(nextElement, transaction) {
284+
receiveComponent: function(nextElement, transaction, context) {
285+
invariant(context !== undefined, "Context is required parameter");
281286
if (nextElement === this._currentElement &&
282287
nextElement._owner != null) {
283288
// Since elements are immutable after the owner is rendered,
@@ -293,7 +298,8 @@ ReactDOMComponent.Mixin = {
293298
ReactComponent.Mixin.receiveComponent.call(
294299
this,
295300
nextElement,
296-
transaction
301+
transaction,
302+
context
297303
);
298304
},
299305

@@ -310,16 +316,19 @@ ReactDOMComponent.Mixin = {
310316
updateComponent: ReactPerf.measure(
311317
'ReactDOMComponent',
312318
'updateComponent',
313-
function(transaction, prevElement, nextElement) {
319+
function(transaction, prevElement, nextElement, context) {
320+
if(context === undefined) throw new Error("Context required for mounting");
321+
if(context === null) context = this._context;
314322
assertValidProps(this._currentElement.props);
315323
ReactComponent.Mixin.updateComponent.call(
316324
this,
317325
transaction,
318326
prevElement,
319-
nextElement
327+
nextElement,
328+
context
320329
);
321330
this._updateDOMProperties(prevElement.props, transaction);
322-
this._updateDOMChildren(prevElement.props, transaction);
331+
this._updateDOMChildren(prevElement.props, transaction, context);
323332
}
324333
),
325334

@@ -425,7 +434,8 @@ ReactDOMComponent.Mixin = {
425434
* @param {object} lastProps
426435
* @param {ReactReconcileTransaction} transaction
427436
*/
428-
_updateDOMChildren: function(lastProps, transaction) {
437+
_updateDOMChildren: function(lastProps, transaction, context) {
438+
invariant(context !== undefined, "Context is required parameter");
429439
var nextProps = this.props;
430440

431441
var lastContent =
@@ -449,7 +459,7 @@ ReactDOMComponent.Mixin = {
449459
var lastHasContentOrHtml = lastContent != null || lastHtml != null;
450460
var nextHasContentOrHtml = nextContent != null || nextHtml != null;
451461
if (lastChildren != null && nextChildren == null) {
452-
this.updateChildren(null, transaction);
462+
this.updateChildren(null, transaction, context);
453463
} else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
454464
this.updateTextContent('');
455465
}
@@ -466,7 +476,7 @@ ReactDOMComponent.Mixin = {
466476
);
467477
}
468478
} else if (nextChildren != null) {
469-
this.updateChildren(nextChildren, transaction);
479+
this.updateChildren(nextChildren, transaction, context);
470480
}
471481
},
472482

src/browser/ui/ReactMount.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ var ReactInstanceHandles = require('ReactInstanceHandles');
2020
var ReactInstanceMap = require('ReactInstanceMap');
2121
var ReactPerf = require('ReactPerf');
2222

23+
var emptyObject = require('emptyObject');
2324
var containsNode = require('containsNode');
2425
var deprecated = require('deprecated');
2526
var getReactRootElementInContainer = require('getReactRootElementInContainer');
@@ -327,10 +328,12 @@ var ReactMount = {
327328
componentInstance,
328329
container
329330
);
331+
330332
componentInstance.mountComponentIntoNode(
331333
reactRootID,
332334
container,
333-
shouldReuseMarkup
335+
shouldReuseMarkup,
336+
emptyObject
334337
);
335338

336339
if (__DEV__) {

src/browser/ui/__tests__/ReactDOMComponent-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ describe('ReactDOMComponent', function() {
281281

282282
genMarkup = function(props) {
283283
var transaction = new ReactReconcileTransaction();
284-
return (new NodeStub(props))._createContentMarkup(transaction);
284+
return (new NodeStub(props))._createContentMarkup(transaction, {});
285285
};
286286

287287
this.addMatchers({
@@ -326,7 +326,7 @@ describe('ReactDOMComponent', function() {
326326
_owner: null,
327327
_context: null
328328
});
329-
return stubComponent.mountComponent('test', transaction, 0);
329+
return stubComponent.mountComponent('test', transaction, 0, {});
330330
};
331331
});
332332

src/browser/ui/dom/__tests__/Danger-test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe('Danger', function() {
3232
it('should render markup', function() {
3333
var markup = instantiateReactComponent(
3434
<div />
35-
).mountComponent('.rX', transaction, 0);
35+
).mountComponent('.rX', transaction, 0, {});
3636
var output = Danger.dangerouslyRenderMarkup([markup])[0];
3737

3838
expect(output.nodeName).toBe('DIV');
@@ -44,7 +44,7 @@ describe('Danger', function() {
4444
).mountComponent(
4545
'.rX',
4646
transaction,
47-
0
47+
0, {}
4848
);
4949
var output = Danger.dangerouslyRenderMarkup([markup])[0];
5050

@@ -55,7 +55,7 @@ describe('Danger', function() {
5555
it('should render wrapped markup', function() {
5656
var markup = instantiateReactComponent(
5757
<th />
58-
).mountComponent('.rX', transaction, 0);
58+
).mountComponent('.rX', transaction, 0, {});
5959
var output = Danger.dangerouslyRenderMarkup([markup])[0];
6060

6161
expect(output.nodeName).toBe('TH');

src/core/ReactComponent.js

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,18 @@ var ReactComponent = {
238238
// All components start unmounted.
239239
this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
240240

241+
// Object/map containing variables defined in the mount context.
242+
// Value is null iff ComponentLifeCycle.UNMOUNTED
243+
this._context = null;
244+
241245
// See ReactUpdates.
242246
this._pendingCallbacks = null;
243247

244248
// We keep the old element and a reference to the pending element
245249
// to track updates.
246250
this._currentElement = element;
247251
this._pendingElement = null;
252+
this._pendingContext = null;
248253
},
249254

250255
/**
@@ -261,7 +266,8 @@ var ReactComponent = {
261266
* @return {?string} Rendered markup to be inserted into the DOM.
262267
* @internal
263268
*/
264-
mountComponent: function(rootID, transaction, mountDepth) {
269+
mountComponent: function(rootID, transaction, mountDepth, context) {
270+
invariant(context !== undefined, "Context is required parameter");
265271
invariant(
266272
!this.isMounted(),
267273
'mountComponent(%s, ...): Can only mount an unmounted component. ' +
@@ -276,6 +282,7 @@ var ReactComponent = {
276282
}
277283
this._rootNodeID = rootID;
278284
this._lifeCycleState = ComponentLifeCycle.MOUNTED;
285+
this._context = context;
279286
this._mountDepth = mountDepth;
280287
// Effectively: return '';
281288
},
@@ -302,6 +309,7 @@ var ReactComponent = {
302309
unmountIDFromEnvironment(this._rootNodeID);
303310
this._rootNodeID = null;
304311
this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
312+
this._context = null;
305313
},
306314

307315
/**
@@ -315,13 +323,15 @@ var ReactComponent = {
315323
* @param {ReactReconcileTransaction} transaction
316324
* @internal
317325
*/
318-
receiveComponent: function(nextElement, transaction) {
326+
receiveComponent: function(nextElement, transaction, context) {
327+
invariant(context !== undefined, "Context is required parameter");
319328
invariant(
320329
this.isMounted(),
321330
'receiveComponent(...): Can only update a mounted component.'
322331
);
323332
this._pendingElement = nextElement;
324-
this.performUpdateIfNecessary(transaction);
333+
this._context = context;
334+
this.performUpdateIfNecessary(transaction, context);
325335
},
326336

327337
/**
@@ -336,11 +346,12 @@ var ReactComponent = {
336346
}
337347
var prevElement = this._currentElement;
338348
var nextElement = this._pendingElement;
349+
var nextContext = this._pendingContext;
339350
this._currentElement = nextElement;
340351
this.props = nextElement.props;
341352
this._owner = nextElement._owner;
342353
this._pendingElement = null;
343-
this.updateComponent(transaction, prevElement, nextElement);
354+
this.updateComponent(transaction, prevElement, nextElement, nextContext);
344355
},
345356

346357
/**
@@ -351,7 +362,8 @@ var ReactComponent = {
351362
* @param {object} nextElement
352363
* @internal
353364
*/
354-
updateComponent: function(transaction, prevElement, nextElement) {
365+
updateComponent: function(transaction, prevElement, nextElement, context) {
366+
invariant(context !== undefined, "Context is required parameter");
355367
// If either the owner or a `ref` has changed, make sure the newest owner
356368
// has stored a reference to `this`, and the previous owner (if different)
357369
// has forgotten the reference to `this`. We use the element instead
@@ -386,15 +398,21 @@ var ReactComponent = {
386398
* @internal
387399
* @see {ReactMount.render}
388400
*/
389-
mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {
401+
mountComponentIntoNode: function(
402+
rootID,
403+
container,
404+
shouldReuseMarkup,
405+
context) {
406+
invariant(context !== undefined, "Context is required parameter");
390407
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
391408
transaction.perform(
392409
this._mountComponentIntoNode,
393410
this,
394411
rootID,
395412
container,
396413
transaction,
397-
shouldReuseMarkup
414+
shouldReuseMarkup,
415+
context
398416
);
399417
ReactUpdates.ReactReconcileTransaction.release(transaction);
400418
},
@@ -411,8 +429,10 @@ var ReactComponent = {
411429
rootID,
412430
container,
413431
transaction,
414-
shouldReuseMarkup) {
415-
var markup = this.mountComponent(rootID, transaction, 0);
432+
shouldReuseMarkup,
433+
context) {
434+
invariant(context !== undefined, "Context is required parameter");
435+
var markup = this.mountComponent(rootID, transaction, 0, context);
416436
mountImageIntoNode(markup, container, shouldReuseMarkup);
417437
},
418438

0 commit comments

Comments
 (0)