diff --git a/packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js b/packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js
index 74a209753..797df863b 100644
--- a/packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js
+++ b/packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js
@@ -15,6 +15,8 @@ import {
Element,
ForwardRef,
Fragment,
+ isContextConsumer,
+ isContextProvider,
isElement,
isForwardRef,
isPortal,
@@ -241,6 +243,18 @@ function nodeToHostNode(_node) {
return mapper(node);
}
+function getProviderDefaultValue(Provider) {
+ // React stores references to the Provider's defaultValue differently across versions.
+ if ('_defaultValue' in Provider._context) {
+ return Provider._context._defaultValue;
+ }
+ throw new Error('Enzyme Internal Error: can’t figure out how to get Provider’s default value');
+}
+
+function makeFakeElement(type) {
+ return { $$typeof: Element, type };
+}
+
const eventOptions = { animation: true };
class ReactSixteenThreeAdapter extends EnzymeAdapter {
@@ -357,11 +371,30 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter {
let isDOM = false;
let cachedNode = null;
return {
- render(el, context) {
+ render(el, context, {
+ providerValues = new Map(),
+ } = {}) {
cachedNode = el;
/* eslint consistent-return: 0 */
if (typeof el.type === 'string') {
isDOM = true;
+ } else if (isContextProvider(el)) {
+ providerValues.set(el.type, el.props.value);
+ const MockProvider = Object.assign(
+ props => props.children,
+ el.type,
+ );
+ return withSetStateAllowed(() => renderer.render({ ...el, type: MockProvider }));
+ } else if (isContextConsumer(el)) {
+ const Provider = adapter.getProviderFromConsumer(el.type);
+ const value = providerValues.has(Provider)
+ ? providerValues.get(Provider)
+ : getProviderDefaultValue(Provider);
+ const MockConsumer = Object.assign(
+ props => props.children(value),
+ el.type,
+ );
+ return withSetStateAllowed(() => renderer.render({ ...el, type: MockConsumer }));
} else {
isDOM = false;
const { type: Component } = el;
@@ -539,13 +572,19 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter {
}
isCustomComponent(type) {
- const fakeElement = { $$typeof: Element, type };
+ const fakeElement = makeFakeElement(type);
return !!type && (
typeof type === 'function'
|| isForwardRef(fakeElement)
+ || isContextProvider(fakeElement)
+ || isContextConsumer(fakeElement)
);
}
+ isContextConsumer(type) {
+ return !!type && isContextConsumer(makeFakeElement(type));
+ }
+
isCustomComponentElement(inst) {
if (!inst || !this.isValidElement(inst)) {
return false;
@@ -553,6 +592,14 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter {
return this.isCustomComponent(inst.type);
}
+ getProviderFromConsumer(Consumer) {
+ const { Provider } = Consumer || {};
+ if (Provider) {
+ return Provider;
+ }
+ throw new Error('Enzyme Internal Error: can’t figure out how to get Provider from Consumer');
+ }
+
createElement(...args) {
return React.createElement(...args);
}
diff --git a/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js b/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js
index a9d4c6460..9667cc6c0 100644
--- a/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js
+++ b/packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js
@@ -18,6 +18,8 @@ import {
Element,
ForwardRef,
Fragment,
+ isContextConsumer,
+ isContextProvider,
isElement,
isForwardRef,
isMemo,
@@ -303,6 +305,21 @@ function wrapAct(fn) {
return returnVal;
}
+function getProviderDefaultValue(Provider) {
+ // React stores references to the Provider's defaultValue differently across versions.
+ if ('_defaultValue' in Provider._context) {
+ return Provider._context._defaultValue;
+ }
+ if ('_currentValue' in Provider._context) {
+ return Provider._context._currentValue;
+ }
+ throw new Error('Enzyme Internal Error: can’t figure out how to get Provider’s default value');
+}
+
+function makeFakeElement(type) {
+ return { $$typeof: Element, type };
+}
+
class ReactSixteenAdapter extends EnzymeAdapter {
constructor() {
super();
@@ -454,11 +471,30 @@ class ReactSixteenAdapter extends EnzymeAdapter {
};
return {
- render(el, unmaskedContext) {
+ render(el, unmaskedContext, {
+ providerValues = new Map(),
+ } = {}) {
cachedNode = el;
/* eslint consistent-return: 0 */
if (typeof el.type === 'string') {
isDOM = true;
+ } else if (isContextProvider(el)) {
+ providerValues.set(el.type, el.props.value);
+ const MockProvider = Object.assign(
+ props => props.children,
+ el.type,
+ );
+ return withSetStateAllowed(() => renderer.render({ ...el, type: MockProvider }));
+ } else if (isContextConsumer(el)) {
+ const Provider = adapter.getProviderFromConsumer(el.type);
+ const value = providerValues.has(Provider)
+ ? providerValues.get(Provider)
+ : getProviderDefaultValue(Provider);
+ const MockConsumer = Object.assign(
+ props => props.children(value),
+ el.type,
+ );
+ return withSetStateAllowed(() => renderer.render({ ...el, type: MockConsumer }));
} else {
isDOM = false;
const { type: Component } = el;
@@ -673,13 +709,19 @@ class ReactSixteenAdapter extends EnzymeAdapter {
}
isCustomComponent(type) {
- const fakeElement = { $$typeof: Element, type };
+ const fakeElement = makeFakeElement(type);
return !!type && (
typeof type === 'function'
|| isForwardRef(fakeElement)
+ || isContextProvider(fakeElement)
+ || isContextConsumer(fakeElement)
);
}
+ isContextConsumer(type) {
+ return !!type && isContextConsumer(makeFakeElement(type));
+ }
+
isCustomComponentElement(inst) {
if (!inst || !this.isValidElement(inst)) {
return false;
@@ -687,6 +729,22 @@ class ReactSixteenAdapter extends EnzymeAdapter {
return this.isCustomComponent(inst.type);
}
+ getProviderFromConsumer(Consumer) {
+ // React stores references to the Provider on a Consumer differently across versions.
+ if (Consumer) {
+ let Provider;
+ if (Consumer.Provider) {
+ ({ Provider } = Consumer);
+ } else if (Consumer._context) {
+ ({ Provider } = Consumer._context);
+ }
+ if (Provider) {
+ return Provider;
+ }
+ }
+ throw new Error('Enzyme Internal Error: can’t figure out how to get Provider from Consumer');
+ }
+
createElement(...args) {
return React.createElement(...args);
}
diff --git a/packages/enzyme-test-suite/test/Adapter-spec.jsx b/packages/enzyme-test-suite/test/Adapter-spec.jsx
index 0745e245b..8f083953a 100644
--- a/packages/enzyme-test-suite/test/Adapter-spec.jsx
+++ b/packages/enzyme-test-suite/test/Adapter-spec.jsx
@@ -1169,7 +1169,40 @@ Warning: Failed Adapter-spec type: Invalid Adapter-spec \`foo\` of type \`string
});
itIf(is('>=16.3'), 'returns true for forward refs', () => {
- expect(adapter.isCustomComponent(React.forwardRef(() => null))).to.equal(true);
+ expect(adapter.isCustomComponent(forwardRef(() => null))).to.equal(true);
+ });
+ });
+
+ describeIf(is('>= 16.3'), 'isContextConsumer(type)', () => {
+ it('returns true for createContext() Consumers', () => {
+ expect(adapter.isContextConsumer(createContext().Consumer)).to.equal(true);
+ });
+
+ it('returns false for everything else', () => {
+ expect(adapter.isContextConsumer(null)).to.equal(false);
+ expect(adapter.isContextConsumer(true)).to.equal(false);
+ expect(adapter.isContextConsumer(undefined)).to.equal(false);
+ expect(adapter.isContextConsumer(false)).to.equal(false);
+ expect(adapter.isContextConsumer(() =>
)).to.equal(false);
+ expect(adapter.isContextConsumer(forwardRef(() => null))).to.equal(false);
+ expect(adapter.isContextConsumer(createContext().Provider)).to.equal(false);
+ });
+ });
+
+ describeIf(is('>= 16.3'), 'getProviderFromConsumer(Consumer)', () => {
+ it('gets a createContext() Provider from a Consumer', () => {
+ const Context = createContext();
+
+ expect(adapter.getProviderFromConsumer(Context.Consumer)).to.equal(Context.Provider);
+ });
+
+ it('throws an internal error if something that is not a Consumer is passed', () => {
+ expect(() => adapter.getProviderFromConsumer(null)).to.throw(
+ 'Enzyme Internal Error: can’t figure out how to get Provider from Consumer',
+ );
+ expect(() => adapter.getProviderFromConsumer({})).to.throw(
+ 'Enzyme Internal Error: can’t figure out how to get Provider from Consumer',
+ );
});
});
});
diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
index 833b37b46..ebec55c34 100644
--- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
+++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
@@ -261,6 +261,53 @@ describeWithDOM('mount', () => {
expect(wrapper.text()).to.equal('Context says: I can be set!');
});
+ describeIf(is('>= 16.3'), 'with createContext()', () => {
+ let Context1;
+ let Context2;
+
+ function WrappingComponent(props) {
+ const { value1, value2, children } = props;
+ return (
+
+
+ {children}
+
+
+ );
+ }
+
+ function Component() {
+ return (
+
+ {value1 => (
+
+ {value2 => (
+ Value 1: {value1}; Value 2: {value2}
+ )}
+
+ )}
+
+ );
+ }
+
+ beforeEach(() => {
+ Context1 = createContext('default1');
+ Context2 = createContext('default2');
+ });
+
+ it('renders', () => {
+ const wrapper = mount(, {
+ wrappingComponent: WrappingComponent,
+ wrappingComponentProps: {
+ value1: 'one',
+ value2: 'two',
+ },
+ });
+
+ expect(wrapper.text()).to.equal('Value 1: one; Value 2: two');
+ });
+ });
+
it('throws an error if the wrappingComponent does not render its children', () => {
class BadWrapper extends React.Component {
render() {
@@ -437,20 +484,50 @@ describeWithDOM('mount', () => {
expect(wrapper.context('name')).to.equal(context.name);
});
- itIf(is('>= 16.3'), 'finds elements through Context elements', () => {
- const { Provider, Consumer } = createContext('');
+ describeIf(is('>= 16.3'), 'createContext()', () => {
+ let Context;
- class Foo extends React.Component {
- render() {
- return (
- {value => {value}}
- );
+ beforeEach(() => {
+ Context = createContext('hello');
+ });
+
+ it('finds elements through Context elements', () => {
+ class Foo extends React.Component {
+ render() {
+ return (
+ {value => {value}}
+ );
+ }
}
- }
- const wrapper = mount(
);
+ const wrapper = mount(
);
+
+ expect(wrapper.find('span').text()).to.equal('foo');
+ });
- expect(wrapper.find('span').text()).to.equal('foo');
+ it('can render a as the root', () => {
+ const wrapper = mount(
+
+ {value => {value}
}
+ ,
+ );
+ expect(wrapper.text()).to.equal('cool');
+
+ wrapper.setProps({ value: 'test' });
+ expect(wrapper.text()).to.equal('test');
+ });
+
+ it('can render a as the root', () => {
+ const wrapper = mount(
+ {value => {value}
},
+ );
+ expect(wrapper.text()).to.equal('hello');
+
+ wrapper.setProps({
+ children: value => Value is: {value}
,
+ });
+ expect(wrapper.text()).to.equal('Value is: hello');
+ });
});
describeIf(is('>= 16.3'), 'forwarded ref Components', () => {
diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
index 831f711bb..c3e736e33 100644
--- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
+++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
@@ -270,6 +270,54 @@ describe('shallow', () => {
expect(wrapper.text()).to.equal('Context says: I can be set!');
});
+ describeIf(is('>= 16.3'), 'with createContext()', () => {
+ let Context1;
+ let Context2;
+ beforeEach(() => {
+ Context1 = createContext('default1');
+ Context2 = createContext('default2');
+ });
+
+ function WrappingComponent(props) {
+ const { value1, value2, children } = props;
+ return (
+
+
+ {children}
+
+
+ );
+ }
+
+ function Component() {
+ return (
+
+ {value1 => (
+
+ {value2 => (
+ Value 1: {value1}; Value 2: {value2}
+ )}
+
+ )}
+
+ );
+ }
+
+ it('renders', () => {
+ const wrapper = shallow(, {
+ wrappingComponent: WrappingComponent,
+ wrappingComponentProps: {
+ value1: 'one',
+ value2: 'two',
+ },
+ });
+ const consumer1 = wrapper.find(Context1.Consumer).dive();
+ const consumer2 = consumer1.find(Context2.Consumer).dive();
+
+ expect(consumer2.text()).to.equal('Value 1: one; Value 2: two');
+ });
+ });
+
it('throws an error if the wrappingComponent does not render its children', () => {
class BadWrapper extends React.Component {
render() {
@@ -415,6 +463,145 @@ describe('shallow', () => {
expect(wrapper.find('.child2')).to.have.lengthOf(1);
});
+ describeIf(is('>= 16.3'), 'createContext()', () => {
+ describe('rendering as root:', () => {
+ let Context;
+
+ beforeEach(() => {
+ Context = createContext('cool');
+ });
+
+ describe('', () => {
+ it('can be rendered as the root', () => {
+ const wrapper = shallow(
+
+
+ {value => {value}
}
+
+ ,
+ );
+ expect(wrapper.debug()).to.eql(`
+
+ [function]
+
+ `.trim());
+ });
+
+ it('supports changing the value', () => {
+ const wrapper = shallow(
+
+
+ {value => {value}
}
+
+ ,
+ );
+ wrapper.setProps({ value: 'world' });
+ expect(wrapper.find(Context.Consumer).dive().text()).to.eql('world');
+ });
+ });
+
+ describe('', () => {
+ function DivRenderer({ children }) {
+ return {children}
;
+ }
+ it('can be rendered as the root', () => {
+ const wrapper = shallow(
+
+ {value => {value}}
+ ,
+ );
+ expect(wrapper.debug()).to.eql(`
+
+ cool
+
+ `.trim());
+ });
+
+ it('supports changing the children', () => {
+ const wrapper = shallow(
+
+ {value => {value}}
+ ,
+ );
+ wrapper.setProps({ children: value => Changed: {value} });
+ expect(wrapper.find(DivRenderer).dive().text()).to.eql('Changed: cool');
+ });
+ });
+ });
+
+ describe('dive() on Provider and Consumer', () => {
+ let Provider;
+ let Consumer;
+
+ beforeEach(() => {
+ ({ Provider, Consumer } = React.createContext('howdy!'));
+ });
+
+ class Consumes extends React.Component {
+ render() {
+ return (
+
+ {value => {value}}
+
+ );
+ }
+ }
+
+ class Provides extends React.Component {
+ render() {
+ const { children } = this.props;
+
+ return (
+
+ );
+ }
+ }
+
+ class MyComponent extends React.Component {
+ render() {
+ return (
+
+ );
+ }
+ }
+
+ it('works on a Provider', () => {
+ const wrapper = shallow();
+ const provides = wrapper.find(Provides).dive();
+ const provider = provides.find(Provider).dive();
+ expect(provider.text()).to.equal('');
+ });
+
+ it('always gives the default provider value if dive()ing directly to a ', () => {
+ // Diving directly on a consumer will give you the default value
+ const wrapper = shallow();
+ const consumes = wrapper.find(Consumes).dive();
+ const consumer = consumes.find(Consumer).dive();
+ expect(consumer.text()).to.equal('howdy!');
+ });
+
+ it('gives the actual value if one dive()s it', () => {
+ const wrapper = shallow();
+ const provides = wrapper.find(Provides).dive();
+ const provider = provides.find(Provider).dive();
+ const consumes = provider.find(Consumes).dive();
+ const consumer = consumes.find(Consumer).dive();
+ expect(consumer.text()).to.equal('foo');
+ });
+
+ it('does not leak values across roots', () => {
+ const wrapper = shallow();
+ const provides = wrapper.find(Provides).dive();
+ const provider = provides.find(Provider).dive();
+ expect(provider).to.have.lengthOf(1);
+
+ const consumes = wrapper.find(Consumes).dive();
+ const consumer = consumes.find(Consumer).dive();
+ expect(consumer.text()).to.equal('howdy!');
+ });
+ });
+ });
+
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
it('can pass in context', () => {
const SimpleComponent = (props, context) => (
diff --git a/packages/enzyme-test-suite/test/shared/methods/getWrappingComponent.jsx b/packages/enzyme-test-suite/test/shared/methods/getWrappingComponent.jsx
index b90555c1a..c9e37f5f4 100644
--- a/packages/enzyme-test-suite/test/shared/methods/getWrappingComponent.jsx
+++ b/packages/enzyme-test-suite/test/shared/methods/getWrappingComponent.jsx
@@ -183,6 +183,31 @@ export default function describeGetWrappingComponent({
}
});
+ itIf(is('>= 16.3'), 'updates a if it is rendered as root', () => {
+ const Context = React.createContext();
+ function WrappingComponent(props) {
+ const { value, children } = props;
+ return (
+
+ {children}
+
+ );
+ }
+ const wrapper = Wrap((
+
+ {value => {value}
}
+
+ ), {
+ wrappingComponent: WrappingComponent,
+ wrappingComponentProps: { value: 'hello!' },
+ });
+ const wrappingComponent = wrapper.getWrappingComponent();
+ expect(wrapper.text()).to.equal('hello!');
+
+ wrappingComponent.setProps({ value: 'goodbye!' });
+ expect(wrapper.text()).to.equal('goodbye!');
+ });
+
itIf(!isShallow, 'handles a partial prop update', () => {
const wrapper = Wrap(, {
wrappingComponent: MyWrappingComponent,
diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js
index 4058847fc..c358fac71 100644
--- a/packages/enzyme/src/ShallowWrapper.js
+++ b/packages/enzyme/src/ShallowWrapper.js
@@ -45,6 +45,7 @@ const CHILD_CONTEXT = sym('__childContext__');
const WRAPPING_COMPONENT = sym('__wrappingComponent__');
const PRIMARY_WRAPPER = sym('__primaryWrapper__');
const ROOT_FINDER = sym('__rootFinder__');
+const PROVIDER_VALUES = sym('__providerValues__');
/**
* Finds all nodes in the current wrapper nodes' render trees that match the provided predicate
@@ -313,14 +314,18 @@ function deepRender(wrapper, target, adapter) {
* @param {WrappingComponentWrapper} wrapper The `WrappingComponentWrapper` for a
* `wrappingComponent`
* @param {Adapter} adapter An Enzyme adapter
- * @returns {object} The context collected
+ * @returns {object} An object containing an object of legacy context values and a Map of
+ * `createContext()` Provider values.
*/
function getContextFromWrappingComponent(wrapper, adapter) {
const rootFinder = deepRender(wrapper, wrapper[ROOT_FINDER], adapter);
if (!rootFinder) {
throw new Error('`wrappingComponent` must render its children!');
}
- return rootFinder[OPTIONS].context;
+ return {
+ legacyContext: rootFinder[OPTIONS].context,
+ providerValues: rootFinder[PROVIDER_VALUES],
+ };
}
/**
@@ -338,6 +343,7 @@ function getContextFromWrappingComponent(wrapper, adapter) {
function makeShallowOptions(nodes, root, passedOptions, wrapper) {
const options = makeOptions(passedOptions);
const adapter = getAdapter(passedOptions);
+ privateSet(options, PROVIDER_VALUES, passedOptions[PROVIDER_VALUES]);
if (root || !isCustomComponent(options.wrappingComponent, adapter)) {
return options;
}
@@ -347,16 +353,18 @@ function makeShallowOptions(nodes, root, passedOptions, wrapper) {
const { node: wrappedNode, RootFinder } = adapter.wrapWithWrappingComponent(nodes, options);
// eslint-disable-next-line no-use-before-define
const wrappingComponent = new WrappingComponentWrapper(wrappedNode, wrapper, RootFinder);
- const wrappingComponentContext = getContextFromWrappingComponent(
- wrappingComponent, adapter,
- );
+ const {
+ legacyContext: wrappingComponentLegacyContext,
+ providerValues: wrappingComponentProviderValues,
+ } = getContextFromWrappingComponent(wrappingComponent, adapter);
privateSet(wrapper, WRAPPING_COMPONENT, wrappingComponent);
return {
...options,
context: {
...options.context,
- ...wrappingComponentContext,
+ ...wrappingComponentLegacyContext,
},
+ [PROVIDER_VALUES]: wrappingComponentProviderValues,
};
}
@@ -385,10 +393,12 @@ class ShallowWrapper {
privateSet(this, UNRENDERED, nodes);
const renderer = adapter.createRenderer({ mode: 'shallow', ...options });
privateSet(this, RENDERER, renderer);
- this[RENDERER].render(nodes, options.context);
+ const providerValues = new Map(options[PROVIDER_VALUES] || []);
+ this[RENDERER].render(nodes, options.context, { providerValues });
const renderedNode = this[RENDERER].getNode();
privateSetNodes(this, getRootNode(renderedNode));
privateSet(this, OPTIONS, options);
+ privateSet(this, PROVIDER_VALUES, providerValues);
const { instance } = renderedNode;
if (instance && !options.disableLifecycleMethods) {
@@ -415,6 +425,7 @@ class ShallowWrapper {
privateSetNodes(this, nodes);
privateSet(this, OPTIONS, root[OPTIONS]);
privateSet(this, ROOT_NODES, root[NODES]);
+ privateSet(this, PROVIDER_VALUES, null);
}
}
@@ -612,7 +623,9 @@ class ShallowWrapper {
);
}
if (props) this[UNRENDERED] = cloneElement(adapter, this[UNRENDERED], props);
- this[RENDERER].render(this[UNRENDERED], nextContext);
+ this[RENDERER].render(this[UNRENDERED], nextContext, {
+ providerValues: this[PROVIDER_VALUES],
+ });
if (shouldComponentUpdateSpy) {
shouldRender = shouldComponentUpdateSpy.getLastReturnValue();
shouldComponentUpdateSpy.restore();
@@ -1659,14 +1672,16 @@ class ShallowWrapper {
if (!isCustomComponentElement(el, adapter)) {
throw new TypeError(`ShallowWrapper::${name}() can only be called on components`);
}
- return this.wrap(el, null, {
+ const childOptions = {
...this[OPTIONS],
...options,
context: options.context || {
...this[OPTIONS].context,
...this[ROOT][CHILD_CONTEXT],
},
- });
+ };
+ privateSet(childOptions, PROVIDER_VALUES, this[ROOT][PROVIDER_VALUES]);
+ return this.wrap(el, null, childOptions);
});
}
@@ -1686,14 +1701,35 @@ class ShallowWrapper {
* `wrappingComponent` re-renders.
*/
function updatePrimaryRootContext(wrappingComponent) {
- const context = getContextFromWrappingComponent(
- wrappingComponent,
- getAdapter(wrappingComponent[OPTIONS]),
- );
- wrappingComponent[PRIMARY_WRAPPER].setContext({
+ const adapter = getAdapter(wrappingComponent[OPTIONS]);
+ const primaryWrapper = wrappingComponent[PRIMARY_WRAPPER];
+ const primaryRenderer = primaryWrapper[RENDERER];
+ const primaryNode = primaryRenderer.getNode();
+ const {
+ legacyContext,
+ providerValues,
+ } = getContextFromWrappingComponent(wrappingComponent, adapter);
+ const prevProviderValues = primaryWrapper[PROVIDER_VALUES];
+
+ primaryWrapper.setContext({
...wrappingComponent[PRIMARY_WRAPPER][OPTIONS].context,
- ...context,
+ ...legacyContext,
});
+ primaryWrapper[PROVIDER_VALUES] = new Map([...prevProviderValues, ...providerValues]);
+
+ if (typeof adapter.isContextConsumer === 'function' && adapter.isContextConsumer(primaryNode.type)) {
+ const Consumer = primaryNode.type;
+ // Adapters with an `isContextConsumer` method will definitely have a `getProviderFromConsumer`
+ // method.
+ const Provider = adapter.getProviderFromConsumer(Consumer);
+ const newValue = providerValues.get(Provider);
+ const oldValue = prevProviderValues.get(Provider);
+
+ // Use referential comparison like React
+ if (newValue !== oldValue) {
+ primaryWrapper.rerender();
+ }
+ }
}
/**