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

Don't use deprecated lifecycle hook #457

Closed
wants to merge 1 commit into from

Conversation

kevva
Copy link

@kevva kevva commented Jun 25, 2018

When testing my app using React.StrictMode, it complains about the usage of this lifecycle hook. It also complains about the componentWillUpdate one, but it seems like it has to stay to avoid flashes of unstyled content.

@kevva kevva requested a review from giuseppeg as a code owner June 25, 2018 18:18
@giuseppeg
Copy link
Collaborator

giuseppeg commented Jun 25, 2018

I think that we shouldn't use the constructor because that is not "async safe". Probably we should move the side effect to render.

@bvaughn I hate to bother you but I would love to know your opinion on this. Basically we are creating or updating styles and I am afraid that if we do so in componentDidMount and componentDidUpdate we'll get FOUC. Is it a terrible idea to move the side effect to render instead?

To give you a bit more context this component renders styles in the head and goes along other components:

<div>
  <_JSXStyle id={123} css="div { color: red } p { color: green }" />
  <p>howdy</p>
</div>

@bvaughn
Copy link

bvaughn commented Jun 26, 2018

Hi!

The constructor, componentWillUpdate, and render are all equally unsafe for side effects because they are all part of the "render" phase.

I don't have a lot of context for this problem, so please take my suggestion with a grain of salt, but I would move the styleSheetRegistry.add call to componentDidMount (where side effects are safe). The browser won't paint/render an update until React finishes invoking the "commit" phase lifecycles so users shouldn't actually see a FOUC (unless styleSheetRegistry.add is somehow async). Any setState calls during this phase are also processed synchronously (i.e. before the browser paints) which is something libraries like react-virtualized rely on for measuring and positioning dynamic content.

This approach won't work for server-side rendering, since nothing "mounts" on the server. If you need to be able to support that as well, you could also leave the code in the constructor and run it only when typeof window === 'undefined'. You might be interested in RFC reactjs/rfcs/pull/8 for a possible better long-term solution.

@giuseppeg
Copy link
Collaborator

giuseppeg commented Jun 26, 2018

@bvaughn 👋 thanks for the clarification! I think you suggested this a while ago but back then I didn't think about moving the side effect to render.

and render are all equally unsafe for side effects

Fair enough! We'll give didMount/Update a try.

@kevva do you have an app to test this out?

Or (better/optional) if you have time add an e2e test? I once added this https://github.com/zeit/styled-jsx/blob/master/test/browser.js but jsdom is not good for these kind of things. You could replace that with tape and tape-run or puppeteer. Here's an example with tape https://github.com/giuseppeg/suitcss-toolkit/tree/master/packages/components-dropdown

@giuseppeg giuseppeg added this to the v3 milestone Jul 18, 2018
@giuseppeg
Copy link
Collaborator

@kevva can you move styleSheetRegistry.add to componentDidMount and styleSheetRegistry.update to componentDidUpdate? Or do you want me to take over this PR?

@giuseppeg
Copy link
Collaborator

Fixed in #464

@giuseppeg giuseppeg closed this Aug 2, 2018
timneutkens pushed a commit that referenced this pull request Aug 31, 2018
We tried master on zeit.co and it seems that when we have the side effects in `componentDidMount` styles are rendered after the content causing transitions to apply to properties that wouldn't otherwise be animated e.g. `padding` similarly to this https://jsfiddle.net/uwbm165z/ (unfortunately I wasn't able to reproduce with React yet but here is my attempt https://codesandbox.io/s/p7q6n6r35m).

In this patch we move the side effect `styleSheetRegistry.add` to `render` making sure that `shouldComponentUpdate` doesn't trigger unnecessary re-renderings. On update we then remove the old styles early enough aka on `getSnapshotBeforeUpdate`.

@bvaughn this is a "followup" of the conversation we had in #457 (comment) Does it make sense?
wroy7860 added a commit to wroy7860/styled-jsx-github-React-and-node that referenced this pull request Sep 19, 2022
We tried master on zeit.co and it seems that when we have the side effects in `componentDidMount` styles are rendered after the content causing transitions to apply to properties that wouldn't otherwise be animated e.g. `padding` similarly to this https://jsfiddle.net/uwbm165z/ (unfortunately I wasn't able to reproduce with React yet but here is my attempt https://codesandbox.io/s/p7q6n6r35m).

In this patch we move the side effect `styleSheetRegistry.add` to `render` making sure that `shouldComponentUpdate` doesn't trigger unnecessary re-renderings. On update we then remove the old styles early enough aka on `getSnapshotBeforeUpdate`.

@bvaughn this is a "followup" of the conversation we had in vercel/styled-jsx#457 (comment) Does it make sense?
ericbrown2716 added a commit to ericbrown2716/styled-jsx-react-repo that referenced this pull request Sep 29, 2022
We tried master on zeit.co and it seems that when we have the side effects in `componentDidMount` styles are rendered after the content causing transitions to apply to properties that wouldn't otherwise be animated e.g. `padding` similarly to this https://jsfiddle.net/uwbm165z/ (unfortunately I wasn't able to reproduce with React yet but here is my attempt https://codesandbox.io/s/p7q6n6r35m).

In this patch we move the side effect `styleSheetRegistry.add` to `render` making sure that `shouldComponentUpdate` doesn't trigger unnecessary re-renderings. On update we then remove the old styles early enough aka on `getSnapshotBeforeUpdate`.

@bvaughn this is a "followup" of the conversation we had in vercel/styled-jsx#457 (comment) Does it make sense?
renawolford6 pushed a commit to renawolford6/styled-jsx-development-react-and-node that referenced this pull request Oct 6, 2022
We tried master on zeit.co and it seems that when we have the side effects in `componentDidMount` styles are rendered after the content causing transitions to apply to properties that wouldn't otherwise be animated e.g. `padding` similarly to this https://jsfiddle.net/uwbm165z/ (unfortunately I wasn't able to reproduce with React yet but here is my attempt https://codesandbox.io/s/p7q6n6r35m).

In this patch we move the side effect `styleSheetRegistry.add` to `render` making sure that `shouldComponentUpdate` doesn't trigger unnecessary re-renderings. On update we then remove the old styles early enough aka on `getSnapshotBeforeUpdate`.

@bvaughn this is a "followup" of the conversation we had in vercel/styled-jsx#457 (comment) Does it make sense?
johnfrench3 pushed a commit to johnfrench3/styled-jsx-Build-React that referenced this pull request Nov 2, 2022
We tried master on zeit.co and it seems that when we have the side effects in `componentDidMount` styles are rendered after the content causing transitions to apply to properties that wouldn't otherwise be animated e.g. `padding` similarly to this https://jsfiddle.net/uwbm165z/ (unfortunately I wasn't able to reproduce with React yet but here is my attempt https://codesandbox.io/s/p7q6n6r35m).

In this patch we move the side effect `styleSheetRegistry.add` to `render` making sure that `shouldComponentUpdate` doesn't trigger unnecessary re-renderings. On update we then remove the old styles early enough aka on `getSnapshotBeforeUpdate`.

@bvaughn this is a "followup" of the conversation we had in vercel/styled-jsx#457 (comment) Does it make sense?
JiachenSmith pushed a commit to JiachenSmith/styled-jsx that referenced this pull request Mar 21, 2023
We tried master on zeit.co and it seems that when we have the side effects in `componentDidMount` styles are rendered after the content causing transitions to apply to properties that wouldn't otherwise be animated e.g. `padding` similarly to this https://jsfiddle.net/uwbm165z/ (unfortunately I wasn't able to reproduce with React yet but here is my attempt https://codesandbox.io/s/p7q6n6r35m).

In this patch we move the side effect `styleSheetRegistry.add` to `render` making sure that `shouldComponentUpdate` doesn't trigger unnecessary re-renderings. On update we then remove the old styles early enough aka on `getSnapshotBeforeUpdate`.

@bvaughn this is a "followup" of the conversation we had in vercel/styled-jsx#457 (comment) Does it make sense?
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

Successfully merging this pull request may close these issues.

3 participants