Skip to content

Client and server id prop does not match despite using SSRProvider #2438

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

Closed
tmoschou opened this issue Oct 8, 2021 · 1 comment
Closed

Comments

@tmoschou
Copy link

tmoschou commented Oct 8, 2021

🐛 Bug Report

When using useId or useSSRSafeId with SSRProvider, Next.js and React Strict Mode, IDs are not generated consistently. In Strict Mode, React deliberately double invoke render, useMemo, etc to detect unexpected side effects logging any errors to the browser console.

🤔 Expected Behavior

Generated IDs should be deterministic. Console should not log any errors.

😯 Current Behavior

Browser logs error with something like

Warning: Prop `id` did not match. Server: "react-aria-1" Client: "react-aria-2"

(Note the off-by-one error).

💁 Possible Reason for bug

It appears that this is due to incrementing the counter inside useMemo, a side-effect which React does not permit:

Remember that the function passed to useMemo runs during rendering. Don’t do anything there that you wouldn’t normally do while rendering. For example, side effects belong in useEffect, not useMemo.
...
You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components.

🔦 Context

This is a transitive dependency of React Bootstrap 2.0.0-rc.0. See react-bootstrap/react-bootstrap#6084

💻 Code Sample

A minimal live example is on CodeSandbox here

pages/index.tsx:

import React from "react";
import { SSRProvider } from "@react-aria/ssr";
import { useId } from "@react-aria/utils";

const App = (): JSX.Element => {
  const id = useId();
  return <div id={id}>Hello</div>;
};

const Page = () => {
  return (
    <SSRProvider>
      <App />
    </SSRProvider>
  );
};
export default Page;

next.config.js:

const nextConfig = {
  // https://nextjs.org/docs/api-reference/next.config.js/react-strict-mode
  reactStrictMode: true
};

module.exports = nextConfig;

🌍 Your Environment

Software Version(s)
@react-aria/ssr 3.1.0
@react-aria/utils 3.9.0
Browser Chome Version 94.0.4606.71 (Official Build) (x86_64)
Operating System MacOS 11.6
@snowystinger
Copy link
Member

Thanks for the issue! I believe it's a duplicate of #2231, so I'm going to close it, if it's different, feel free to reopen

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

2 participants