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

NextJS with Typescript throwing hydration error #1449

Closed
infecting opened this issue May 3, 2022 · 5 comments
Closed

NextJS with Typescript throwing hydration error #1449

infecting opened this issue May 3, 2022 · 5 comments

Comments

@infecting
Copy link

infecting commented May 3, 2022

Current Behavior

Hydration error being thrown in NextJS v12.1.5 React version 18.1.0. Error goes away when replacing the React-Player element with video tag.

Error says:

Unhandled Runtime Error
Error: Hydration failed because the initial UI does not match what was rendered on the server.

Call Stack
throwOnHydrationMismatch
node_modules/react-dom/cjs/react-dom.development.js (14388:0)
tryToClaimNextHydratableInstance
node_modules/react-dom/cjs/react-dom.development.js (14401:0)
updateSuspenseComponent
node_modules/react-dom/cjs/react-dom.development.js (21166:0)
beginWork
node_modules/react-dom/cjs/react-dom.development.js (22453:0)
HTMLUnknownElement.callCallback
node_modules/react-dom/cjs/react-dom.development.js (4161:0)
Object.invokeGuardedCallbackDev
node_modules/react-dom/cjs/react-dom.development.js (4210:0)
invokeGuardedCallback
node_modules/react-dom/cjs/react-dom.development.js (4274:0)
beginWork$1
node_modules/react-dom/cjs/react-dom.development.js (27405:0)
performUnitOfWork
node_modules/react-dom/cjs/react-dom.development.js (26513:0)
workLoopSync
node_modules/react-dom/cjs/react-dom.development.js (26422:0)
renderRootSync
node_modules/react-dom/cjs/react-dom.development.js (26390:0)
performConcurrentWorkOnRoot
node_modules/react-dom/cjs/react-dom.development.js (25694:0)
workLoop
node_modules/scheduler/cjs/scheduler.development.js (266:0)
flushWork
node_modules/scheduler/cjs/scheduler.development.js (239:0)
MessagePort.performWorkUntilDeadline
node_modules/scheduler/cjs/scheduler.development.js (533:0)

Expected Behavior

Expect video element to load without throwing next hydration error.

Steps to Reproduce

  1. Download most recent version of NextJS and create project using yarn create
  2. Install React player using yarn
  3. Use react player in a nested component with a local file in the public directory

Environment

  • URL attempting to play: local file /backing_one.mp4 in public folder
  • Browser: Chrome 100.0.4896.127 (Official Build) (arm64)
  • Operating system: Mac OS Monterey v 12.2
  • jsFiddle example: js fiddle doesn't work with nextjs so code is below

Other Information

export default function Video({bpm, chords}: videoProps) {
  const [chord, setChord] = useState("")
  bpm = (60000/bpm) * 4;
  function getChord(seconds: number) {
    if (seconds == 0) {
        return
    }
    var isBeat = Number((seconds % bpm).toFixed(2));
    console.log(isBeat);
    if (isBeat == 0) {
        var beatNum = (Math.round(Number(seconds / bpm)) % 4);
        console.log(beatNum);
        setChord(chords[beatNum].chord);
        console.log(chords[beatNum].chord);
    };
  };
  return (
      <div>
        <ReactPlayer progressInterval={.001} onProgress={(p) => getChord(p.playedSeconds)} controls url={"/backing_one.mp4"} />
        <p>Current Chord: {chord}</p>
      </div>
  )
}
@infecting
Copy link
Author

I fixed this by checking for if the window has rendered, and then rendering the video component. This fix works but I think some out of the box checks for if the window has rendered could be worth it. Code below:

export default function Video() {
    const [isSSR, setIsSSR] = useState(true);

    useEffect(() => {
        setIsSSR(false);
    }, []);
  return (
      <div>
        {isSSR ? null: <ReactPlayer controls url={"/backing_one.mp4"} />}
      </div>
  )
}

@b4s36t4
Copy link

b4s36t4 commented May 9, 2022

const ReactPlayer = dynamic(() => import("react-player"), { ssr: false });

You can simply use dynamic imports that are available as part of next.js

@wolfgangschoeffel
Copy link

Just found out ref currently is not working properly when using dynamic imports, see #1455

"next": "^12.1.5",
"react-player": "^2.10.1",

@razanfawwaz
Copy link

I fixed this by checking for if the window has rendered, and then rendering the video component. This fix works but I think some out of the box checks for if the window has rendered could be worth it. Code below:

export default function Video() {
    const [isSSR, setIsSSR] = useState(true);

    useEffect(() => {
        setIsSSR(false);
    }, []);
  return (
      <div>
        {isSSR ? null: <ReactPlayer controls url={"/backing_one.mp4"} />}
      </div>
  )
}

wow thank you!

@KesleyDavid
Copy link

Eu consertei isso verificando se a janela foi renderizada e, em seguida, renderizando o componente de vídeo. Essa correção funciona, mas acho que algumas verificações prontas para se a janela renderizada podem valer a pena. Código abaixo:

export default function Video() {
    const [isSSR, setIsSSR] = useState(true);

    useEffect(() => {
        setIsSSR(false);
    }, []);
  return (
      <div>
        {isSSR ? null: <ReactPlayer controls url={"/backing_one.mp4"} />}
      </div>
  )
}

Very good, worked perfectly :D

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