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

React 16 client side render doesn't update DOM's style that comes from SSR #11128

Closed
ohmyhusky opened this issue Oct 6, 2017 · 8 comments
Closed

Comments

@ohmyhusky
Copy link

Do you want to request a feature or report a bug?
bug
What is the current behavior?
React 16 client-side-render have a problem, it can not update the DOM's style, but it can update the prop. More detail on repo below.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template for React 16: https://jsfiddle.net/Luktwrdm/, template for React 15: https://jsfiddle.net/hmbg7e9w/).
I created a repo for this https://github.com/cyl19910101/React-16-SSR-style-problem
What is the expected behavior?
Update DOM's style correctly.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

You are using Chrome Dev 61.0.3163.100 on OS X El Capitan 10.11
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36

React 16.0.0

It does work in previou version like 15.6.2.

@gaearon
Copy link
Collaborator

gaearon commented Oct 6, 2017

This is expected. Please see #11104.

It "worked" in 15 only in the sense that React removed your whole markup and rendered once again on the client. Which produces a jarring experience and we always warned against it.

Please fix the differences between the server and the client render. If you need to render different things on the server and the client, you can do so after mounting as illustrated in this approach: #8017 (comment)

@gaearon gaearon closed this as completed Oct 6, 2017
@ohmyhusky
Copy link
Author

@gaearon Thanks for confirming that's a feature in React 16. Would you mind tell me more detail about "what" will be updated and what will not under React 16? Why I have this question is because in my example,

import React from "react";

const isBrowser = typeof document === "object";

export default function App() {
  return (
    <div
      style={{
        height: "500px",
        backgroundColor: isBrowser ? "skyblue" : "red"
      }}
    >
      {isBrowser ? "browser" : "server"}
    </div>
  );
}

the style "state" got updated, but not the "DOM". However the content inside div ("browser" or "server") got updated. Does this mean that only the "children" prop will be updated? Or we should not rely on this, just do rerender if we need something to be updated according to the browser's Environment?

@gaearon
Copy link
Collaborator

gaearon commented Oct 6, 2017

Does this mean that only the "children" prop will be updated?

With the current strategy, React patches up just text content. This is because it won’t mess up the reconciliation and often happens due to e.g. timestamps. It is harder to do anything meaningful when the difference is e.g. in attributes without making performance worse for everyone.

Or we should not rely on this, just do rerender if we need something to be updated according to the browser's Environment?

Preferably yes, you should just schedule an extra render with setState if you really need it to be different. Although @sebmarkbage is adding a way to intentionally opt into inconsistencies for text in #11126.

So far, the most context you can read on this decision is in #10591. We’ll likely document it more broadly eventually. The action item for this is in reactjs/react.dev#25.

@ohmyhusky
Copy link
Author

@gaearon Thanks a lot! Dan, your answer just as useful as it could be.

@nitish24p
Copy link

@gaearon Is the above case also expected, if on my client render i have a button click which does a setState and changes some value that were different in the original SSR, and the UI doesn't update?

@gaearon
Copy link
Collaborator

gaearon commented Nov 10, 2017

It's a bit hard to say without a minimal repro case.

@bb
Copy link

bb commented Jan 20, 2018

Yet another way to work around this: https://gist.github.com/bb/a6c9cdbdbe253f3a77c5212c827dc3b1

@benpptung
Copy link

benpptung commented May 3, 2018

@gaearon I'm sorry I'm still new to SSR. I'm wondering if #8017 approach still work in React 16.3 to render different things between server and client?

I need to update DOM's style too after SSR, in SSR, it's {height: '110%'} because I don't know the screen height, and in client, I want to update it based on the real screen height, that said {height: 620}.

I've tried #8017, but the style keeps unchanged. Then, I wrap the setState({hasMounted: true}) by setTimeout(_=> this.setState({hasMounted: true}), 10000) 10 seconds, it still doesn't work.

Then, I change hydrate() to render(), it works.

Does it means components mounted via hydrate will never update style ?

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

No branches or pull requests

5 participants