Skip to content

Commit

Permalink
Element: Fix serializer handling of multiple distinct contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Mar 25, 2020
1 parent b7125c0 commit 7704924
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/element/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ Serializes a React element to string.
_Parameters_

- _element_ `WPElement`: Element to serialize.
- _context_ `?Object`: Context object.
- _context_ `[Map]`: Context object.
- _legacyContext_ `?Object`: Legacy context object.

_Returns_
Expand Down
11 changes: 8 additions & 3 deletions packages/element/src/serialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ function getNormalStylePropertyValue( property, value ) {
* Serializes a React element to string.
*
* @param {WPElement} element Element to serialize.
* @param {?Object} context Context object.
* @param {Map=} context Context object.
* @param {?Object} legacyContext Legacy context object.
*
* @return {string} Serialized element.
Expand Down Expand Up @@ -411,11 +411,16 @@ export function renderElement( element, context, legacyContext = {} ) {

switch ( type && type.$$typeof ) {
case Provider.$$typeof:
return renderChildren( props.children, props.value, legacyContext );
context = new Map( context );
context.set( type, props.value );
return renderChildren( props.children, context, legacyContext );

case Consumer.$$typeof:
return renderElement(
props.children( context || type._currentValue ),
props.children(
( context && context.get( type._context.Provider ) ) ||
type._currentValue
),
context,
legacyContext
);
Expand Down
30 changes: 30 additions & 0 deletions packages/element/src/test/serialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,36 @@ describe( 'renderElement()', () => {
expect( result ).toBe( 'inner provided|outer provided' );
} );

it( 'renders proper value through Context API when nested, distinct providers present', () => {
const {
Consumer: FirstConsumer,
Provider: FirstProvider,
} = createContext();
const {
Consumer: SecondConsumer,
Provider: SecondProvider,
} = createContext();

const result = renderElement(
<FirstProvider value="First">
<SecondProvider value="Second">
<FirstConsumer>
{ ( first ) => (
<>
First: { first }, Second:{ ' ' }
<SecondConsumer>
{ ( second ) => second }
</SecondConsumer>
</>
) }
</FirstConsumer>
</SecondProvider>
</FirstProvider>
);

expect( result ).toBe( 'First: First, Second: Second' );
} );

it( 'renders RawHTML as its unescaped children', () => {
const result = renderElement( <RawHTML>{ '<img/>' }</RawHTML> );

Expand Down

0 comments on commit 7704924

Please sign in to comment.