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

v3 prop className did not match warning in Next.js #3590

Open
vaunus opened this issue May 28, 2019 · 50 comments
Open

v3 prop className did not match warning in Next.js #3590

vaunus opened this issue May 28, 2019 · 50 comments
Labels
issue/bug-confirmed Issues about a bug that has been confirmed by a maintainer

Comments

@vaunus
Copy link

vaunus commented May 28, 2019

Hi. I am seeing a warning since upgrading to version 3 with the latest versions of Next.js and React:

Warning: Prop className did not match. Server: "css-1g6gooi" Client: "css-w8afj7-Input"

See this sandbox for my reproduction:
https://codesandbox.io/s/helloworld-g1mb7

@tomlagier
Copy link

Same issue outside of Next.js, but when SSR'd. Using "react-select": "^3.0.4", getting the same error.

@ulysset
Copy link

ulysset commented Jun 5, 2019

Any news on this one? Could it be because of emotion?

@irvelervel
Copy link

Using Next.js and "react-select": "^3.0.4", getting the same error.

@iovoz
Copy link

iovoz commented Jun 25, 2019

Warning: Prop className did not match. Server: "css-1g6gooi" Client: "css-w8afj7-Input"
warningWithoutStack @ react-dom.development.js:506

@z3niths
Copy link

z3niths commented Jun 30, 2019

I've experienced the same problem

Screen Shot 2562-07-01 at 03 33 29

@dicrescenzoa
Copy link

same problem here as well, any idea? 🤔

@gwyneplaine gwyneplaine self-assigned this Jul 8, 2019
@gwyneplaine gwyneplaine added the issue/bug-confirmed Issues about a bug that has been confirmed by a maintainer label Jul 8, 2019
@boscomateo
Copy link

Same here

@maciejmatu
Copy link

I also have this issue. It seems that on the client the components have a different label configuration, because on the backend there is no -Input suffix. Is it possible that emotion uses some kind of an env variable to determine what label format to use? I tried setting different NODE_ENV but it doesn't seem to change anything :/

@maciejmatu
Copy link

maciejmatu commented Aug 2, 2019

Okay, I found out what is the problem! In package.json file of react-select package, there are those two fields:
image

Turns out that next.js selected different module types for different environments. It loaded react-select.cjs.js file for node and react-select.browser.esm.js for browser. I'm not exactly sure why the code in different modules resulted in different classNames (maybe it is connected to different env variables or something else, but I didn't investigate further).

For now the quick fix I found in this thread is to change the resolve field for webpack config to prioritize main field over module and browser when building a bundle.

example:

// next.config.js
module.exports = {
  webpack: config => {
    config.resolve.mainFields = ["main", "browser", "module"];
    return config;
  },
};

The downside is that it can break other packages that must prioritize module, but in my case (for now at least) it fixed this issue. It would be great if someone who understand the codebase further could look into this and help out a bit 😄

@AKharytonchyk
Copy link

Looks like disabling SSR for a particular component works.
https://codesandbox.io/s/hello-world-gox8w

@gwyneplaine
Copy link
Collaborator

Okay, I found out what is the problem! In package.json file of react-select package, there are those two fields:
image

Turns out that next.js selected different module types for different environments. It loaded react-select.cjs.js file for node and react-select.browser.esm.js for browser. I'm not exactly sure why the code in different modules resulted in different classNames (maybe it is connected to different env variables or something else, but I didn't investigate further).

For now the quick fix I found in this thread is to change the resolve field for webpack config to prioritize main field over module and browser when building a bundle.

example:

// next.config.js
module.exports = {
  webpack: config => {
    config.resolve.mainFields = ["main", "browser", "module"];
    return config;
  },
};

The downside is that it can break other packages that must prioritize module, but in my case (for now at least) it fixed this issue. It would be great if someone who understand the codebase further could look into this and help out a bit 😄

thanks for the insight into the problem @maciejmatu, @mitchellhamilton any ideas on how to fix this issue for our next js users?

@emmatown
Copy link
Collaborator

Fixed this with an update to some regex in emotion. An example of it working by reinstalling react-select so the new version of emotion is used: https://codesandbox.io/s/hello-world-jtyix

@JStein92
Copy link

Fixed this with an update to some regex in emotion. An example of it working by reinstalling react-select so the new version of emotion is used: https://codesandbox.io/s/hello-world-jtyix

Still getting this error in 3.1.0

@ciruz
Copy link

ciruz commented Jul 23, 2020

I'm also experiencing the same error now with react-select 3.1.0 and the latest next.js version 9.4.4.

@RickyMarou
Copy link

Using react-select 3.1.0 in a react app that uses SSR (not using next.js but ssr custom made using @loadable and react-router) and still getting the error 😞 .
I guess we will be disabling SSR for that component, which is an okay solution for us 🤷

@marklawlor
Copy link

Setting the inputId and instanceId props fixed the issue for me (you can see it demonstrated in the codesandbox by @mitchellhamilton).

It would be nice for this library to provide a ssr: true option that would automatically generate these values. Otherwise you can set them yourself either via

@bladey bladey reopened this Oct 1, 2020
@bladey bladey added the issue/reviewed Issue has recently been reviewed (mid-2020) label Oct 1, 2020
@bladey
Copy link
Contributor

bladey commented Oct 1, 2020

Thanks for the feedback all, we'll look into this.

@MitchWeiss
Copy link

Hey @bladey, just wondering if you've had a chance to look into this by any chance?

@laleksiunas
Copy link

I can reproduce this hydration mismatch only on Safari browsers (both macOS and iOS) which is rather strange. Trace:

Warning: Prop `className` did not match. Server: "css-b8ldur-Input" Client: "css-19odofu-Promise"
    in div (created by Context.Consumer)
    in EmotionCssPropInternal (created by Input)
    in Input (created by Select)
    in div (created by Context.Consumer)
    in EmotionCssPropInternal (created by ValueContainer)

@Methuselah96
Copy link
Collaborator

Methuselah96 commented Nov 14, 2020

I've started a fork of react-select. Feel free to resubmit this issue on the fork and/or submit a PR to resolve this issue on the fork and we can get it merged and released.

EDIT: 🎉 I've archived the fork now that we've got some momentum in this repo and Jed is involved again. Sorry for the disturbance!

@mediabeastnz
Copy link

👀

@j-fan
Copy link

j-fan commented Feb 12, 2021

I am seeing this issue in react-select v4.1 with React SSR, but it is only affecting Safari. Does anyone have any insights on this?
Here is a simple reproduction: https://codesandbox.io/s/react-ssr-bug-hfp29?file=/src/components/App.jsx

Warning: Prop `className` did not match. Server: "css-b8ldur-Input" Client: "css-1g6gooi"

@marklawlor
Copy link

marklawlor commented Feb 12, 2021

I am seeing this issue in react-select v4.1 with React SSR, but it is only affecting Safari. Does anyone have any insights on this?
Here is a simple reproduction: https://codesandbox.io/s/react-ssr-bug-hfp29?file=/src/components/App.jsx

Warning: Prop `className` did not match. Server: "css-b8ldur-Input" Client: "css-1g6gooi"

Have you tried setting both inputId and instanceId eg https://codesandbox.io/s/hello-world-jtyix

@Methuselah96 Methuselah96 added this to the 5.1 milestone Sep 10, 2021
@Methuselah96
Copy link
Collaborator

Methuselah96 commented Sep 21, 2021

See emotion-js/emotion#2255 for the latest on this. Since it's been confirmed that this is not a production-impacting issue (it's an erroneous console error for Safari in development only) I'm taking this off the 5.1 milestone. #4088 is more important and is where I'll focus my efforts.

@Methuselah96 Methuselah96 removed this from the 5.1 milestone Sep 21, 2021
@philipaarseth
Copy link

It's not really a fix, but you can wrap with a <ClientOnly> HOC such as this
https://www.joshwcomeau.com/react/the-perils-of-rehydration/#abstractions

@shehi
Copy link

shehi commented Feb 19, 2022

This problem is happening on Chrome and FF with NextJS, when component is SSR'ed.

image

@laleksiunas
Copy link

@shehi I think you are experiencing a different problem. Try setting an instanceId prop.

@jakexconniff
Copy link

Having this same issue with Remix, React-Select v5.2.2 on Google Chrome, so it is definitely not Safari. I have set inputId and instanceId.

react-dom.development.js:67 Warning: Prop `className` did not match. Server: " css-6j8wv5-Input" Client: " css-ujecln-Input2"

is what the error message switches to once I add instanceId.

@jdnichollsc
Copy link

It's not really a fix, but you can wrap with a <ClientOnly> HOC such as this https://www.joshwcomeau.com/react/the-perils-of-rehydration/#abstractions

But what happen if I want to have different classes using SSR? I mean, I'm adding classes using Media Queries with react-responsive package but I don't see a good alternative to know that info from server side (I'm using RemixJS) 🤔

@richpixel
Copy link

I was hoping that setting prop classNamePrefix would dismiss the warning, but it looks like it still generates a uid for Input:

Warning: Prop className did not match. Server: "tags-select__input-container css-6j8wv5-Input" Client: "tags-select__input-container css-ujecln-Input2"

@NiklasAbrahamsson
Copy link

Sadly I am having this issue as well and since there doesn't seem to be a viable fix for it yet, i will go with the soultions for now. Will have to come back to this later.

@NedelinaN
Copy link

I get this warning on the latest version of Chrome on MacOS at react 18.2

@tyteen4a03
Copy link

tyteen4a03 commented Oct 17, 2022

Same issue here with Remix.

@pogran
Copy link

pogran commented Oct 27, 2022

I think its the best resolution for now

if (!isMounted) { return <></>; }

@gwyneplaine gwyneplaine removed their assignment Nov 3, 2022
@EvgeniyBudaev
Copy link

Fix in Remix.js

import { useHydrated } from 'remix-utils'; 
const isHydrated = useHydrated();  
isHydrated ? <Select /> : null;  

Fix in Next.js and React.js

import { useEffect, useState } from "react";

export const useMounted = (): { hasMounted: boolean } => {
  const [hasMounted, setHasMounted] = useState(false);
  useEffect(() => {
    setHasMounted(true);
  }, []);
  return { hasMounted };
};

const { hasMounted } = useMounted();

hasMounted ? <Select /> : null;

@phifa
Copy link

phifa commented Dec 22, 2022

@EvgeniyBudaev the thing is, this causes a layout shift. Is it not possible to server side render react-select?

@EvgeniyBudaev
Copy link

@phifa Layout shift due to nulls. This is just an example. Instead of nulls, there can be an element with the same dimensions as select. I didn't make the example complicated. The main idea in solving the problem of server and client hydration.

@phifa
Copy link

phifa commented Dec 23, 2022

@EvgeniyBudaev Yeah i know, my question is, can the component simply not render on the server?

@nick-bigger
Copy link

hey all, is there any movement on this issue ? I don't see any truly viable solution here - we have tons of ReactSelects across our application - is the only solution to wrap all of them in a conditional ? Not only is this tedious and poor DX, it means the initial server code will be missing all of the inputs and then they'll all suddenly pop in.

@cluk3
Copy link

cluk3 commented May 15, 2023

It happens the same to me using Remix. It only happens in development though, I'm pretty sure the main reason is because in development emotion suffixes the generated className with the displayName of the component, and for some reason the on the client the display name of react-select components change from ${Component.displayName} to ${Component.displayName}2 as you can see yourself in the following example error:

Warning: Prop className did not match. Server: "tags-select__input-container css-6j8wv5-Input" Client: "tags-select__input-container css-ujecln-Input2"

@jeffminsungkim
Copy link

Any updates on this thread?
I'm having the same issue on Safari.

react-select v5.7.3 react v18.2.0

@brenoprata10
Copy link

I am also having the same issue.

@mikkpokk
Copy link

mikkpokk commented Sep 6, 2023

<ClientOnly> "fix" is not really fix. It causes layout shifts. Unless you use that component below the fold, layout shifts are not acceptable nowadays, it's UX nightmare.

image

@ZeldOcarina
Copy link

It keeps saying it's closed on this thread but the issue continues.. it has been three years now..

@ZeldOcarina
Copy link

Same issue on Astro.

@Jonydu05
Copy link

Same issue on Astro.

Have you resolved this issue?

@oskarhertzman
Copy link

oskarhertzman commented Sep 2, 2024

Getting similar error when using isSearchable={false}

hydration-error-info.js:63 Warning: Prop `className` did not match. Server: "css-1czm0f-dummyInput-DummyInput" Client: "css-mohuvp-dummyInput-DummyInput"
 <ReactSelect
          ...
            isSearchable={false}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
issue/bug-confirmed Issues about a bug that has been confirmed by a maintainer
Projects
None yet
Development

No branches or pull requests