Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed an issue with nested contexts unwinding when server rendering. Issue #12984 #12985

Merged
merged 8 commits into from Jun 11, 2018
Expand Up @@ -192,32 +192,29 @@ describe('ReactDOMServerIntegration', () => {
expect(e.querySelector('#language').textContent).toBe('english');
});

itRenders(
'nested context unwinding',
async render => {
const Theme = React.createContext('dark');
const Language = React.createContext('french');
itRenders('nested context unwinding', async render => {
const Theme = React.createContext('dark');
const Language = React.createContext('french');

const App = () => (
<div>
<Theme.Provider value="light">
<Language.Provider>
<Theme.Provider value="dark">
<Theme.Consumer>
{theme => <div id="theme1">{theme}</div>}
</Theme.Consumer>
</Theme.Provider>
const App = () => (
<div>
<Theme.Provider value="light">
<Language.Provider>
<Theme.Provider value="dark">
<Theme.Consumer>
{theme => <div id="theme2">{theme}</div>}
{theme => <div id="theme1">{theme}</div>}
</Theme.Consumer>
</Language.Provider>
</Theme.Provider>
</div>
);
let e = await render(<App />);
expect(e.querySelector('#theme1').textContent).toBe('dark');
expect(e.querySelector('#theme2').textContent).toBe('light');
},
);
</Theme.Provider>
<Theme.Consumer>
{theme => <div id="theme2">{theme}</div>}
</Theme.Consumer>
</Language.Provider>
</Theme.Provider>
</div>
);
let e = await render(<App />);
expect(e.querySelector('#theme1').textContent).toBe('dark');
expect(e.querySelector('#theme2').textContent).toBe('light');
});
});
});
7 changes: 5 additions & 2 deletions packages/react-dom/src/server/ReactPartialRenderer.js
Expand Up @@ -693,8 +693,11 @@ class ReactDOMServerRenderer {
for (let i = this.providerIndex; i >= 0; i--) {
// We assume this Flow type is correct because of the index check above.
const priorProvider: ?ReactProvider<any> = this.providerStack[i];
if (priorProvider !== null && priorProvider !== undefined &&
priorProvider.type === provider.type) {
if (
priorProvider !== null &&
priorProvider !== undefined &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These checks aren’t truly necessary, are they? We know they can’t be empty because we’re moving to the left and check the index.

If type system disagrees I think we should do an unsafe cast with a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to. I wasn't sure how strict you wanted to be with the type checking.

priorProvider.type === provider.type
) {
contextPriorProvider = priorProvider;
break;
}
Expand Down