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

Critical bug at [server side render], failure when use [Context.Consumer] in [production] mode only. #16913

Closed
wants to merge 1 commit into from

Conversation

soldovskii
Copy link

@soldovskii soldovskii commented Sep 26, 2019

Hello everyone!
That fix for server side rendering when you use Context.Consumer.

Issues for example in react:
#16848

Issues for example in react-router:
remix-run/react-router#6789
remix-run/react-router#6704

Issues for example in redux-connect:
makeomatic/redux-connect#137

Issues for example in next.js:
vercel/next.js#7167

Bug was in ReactDOMServerRenderer.js since version 16.6.2 and affects.

  • renderToString
  • renderToStaticMarkup
  • renderToNodeStream
  • renderToStaticNodeStream

To reproduce, only in production mode and total bundle, try

const ThemeContext = React.createContext('light');

const Button = () => {
  return (
    <ThemeContext.Provider value="dark">
      <ThemeContext.Consumer>
        {theme => <span>{theme}</span>}
      </ThemeContext.Consumer>
   </ThemeContext.Provider>
  )
}

const appHTML = ReactDomServer.renderToString(<Button />)

console.log(appHTML)

And you will see just <span></span> instead <span>dark</span>

@sizebot
Copy link

sizebot commented Sep 26, 2019

No significant bundle size changes to report.

Generated by 🚫 dangerJS against 843e6b6

@edvinerikson
Copy link
Contributor

Would be nice with a test case as well 🙂

@soldovskii
Copy link
Author

Would be nice with a test case as well 🙂

As far as I understand, the test is difficult to implement, since the error occurs after the separation files on development and production

@soldovskii
Copy link
Author

soldovskii commented Sep 27, 2019

Don't know how, but test will be passed, but after build bug has effect.
May be problem in react, not react-dom

@soldovskii
Copy link
Author

@sebmarkbage @trueadm that code between yours, can you chek it?

@soldovskii soldovskii changed the title Fix SSR via Context.Consumer Critical [bug] in [server side render], failure when use [Context.Consumer] in [production mode] Oct 1, 2019
@soldovskii soldovskii changed the title Critical [bug] in [server side render], failure when use [Context.Consumer] in [production mode] Critical bug in [server side render], failure when use [Context.Consumer] in [production] and mode only. Oct 1, 2019
@edvinerikson
Copy link
Contributor

Probably need a test that runs on the production bundle. However I'm not very familiar how that works. Given that it's only the production bundle that has the bug, it might be a minifier bug causing this.

@soldovskii
Copy link
Author

Maybe, but this PR fix this behavior

@soldovskii
Copy link
Author

In deep, problem in object structure of react element.
In dev it have {_context[thread_id], ...}, in prod {[thread_id], ...}.
Code above my commit has comment about it.

I think problem arose by merge conflict. Condition for check this was shifted to dev block.
But in real this condition need on both: dev and prod modes.

@soldovskii soldovskii changed the title Critical bug in [server side render], failure when use [Context.Consumer] in [production] and mode only. Critical bug at [server side render], failure when use [Context.Consumer] in [production] mode only. Oct 1, 2019
trueadm
trueadm approved these changes Oct 1, 2019
Copy link
Contributor

@trueadm trueadm left a comment

Choose a reason for hiding this comment

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

Ignore my previous approval, that was by mistake (I went back to the wrong browser tab, oops).

Copy link
Contributor

@trueadm trueadm left a comment

Choose a reason for hiding this comment

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

It seems that you're mixing DEV and PROD modes in the same app? You should only have one or the other. Maybe instead we could warn if you're not in DEV but the prod callsite exists, as that would infer there's been a mix up somewhere along the way. It might also be due to mixing contexts from older versions, as per the comment:

https://github.com/facebook/react/blob/master/packages/react-dom/src/server/ReactPartialRenderer.js#L1167-L1178

Either way, this seems like an issue in the packages you're using rather than an underling issue in React.

@soldovskii
Copy link
Author

@trueadm
Can u try this?

  1. git pull https://github.com/soldovskij/all-the-hooks/tree/srr-context
  2. yarn && yarn && start
  3. open localhost:8080 and see <span></span> instead <span>dark</span>

as I understand it production mode

@soldovskii
Copy link
Author

soldovskii commented Oct 2, 2019

Yes, you right. It is was collision in my bundle.
Good experience, thank you =)

@trueadm
Copy link
Contributor

trueadm commented Oct 2, 2019

Awesome. Glad I could help :)

@trueadm trueadm closed this Oct 2, 2019
Copy link

@ernestognw ernestognw left a comment

Choose a reason for hiding this comment

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

Is there any workaround since its difficult to find which one of the context you're using on your application is the one causing the problem. I know that this is a problem regarding other packages, but I would suggest to have an alternative here.

@milos2211
Copy link

milos2211 commented Oct 18, 2019

I have same problem and i tried to create simple component with:

const Span = () => {
  return (
    <ThemeContext.Provider value="dark">
      <ThemeContext.Consumer>
        {theme => <span>{theme}</span>}
      </ThemeContext.Consumer>
    </ThemeContext.Provider>
  )
}

And this is working, but if i change value to object, like this:

const Span = () => {
  return (
    <ThemeContext.Provider value={{theme:"dark"}}>
      <ThemeContext.Consumer>
        {({theme}) => (<span>{theme}</span>)}
      </ThemeContext.Consumer>
    </ThemeContext.Provider>
  )
}

I get

Cannot read property 'theme' of undefined

Both codes are working normally in DEV mode.

Any idea what could be wrong?

Thanks.

@milos2211
Copy link

I realize that i had multiple instances of Context. So when i fixed that, problem went away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants