Next.js Discord

Discord Forum

How can I fix these 3 Hydration Errors ?

Answered
Sun bear posted this in #help-forum
Open in Discord
Sun bearOP
Here is my code:

//app/[lang]/signup/page.tsx
import { getDictionary } from '@/app/translation/dictionary';
import SignUp from '@/components/SignUpProcess/page';
import type { Dictionary } from '@/app/translation/dictionaryTypes';

type Props = {
  params: {
    lang: "en" | "ro";
  }
}

const Page = async (props: Props) => {
    const data = await getDictionary(props.params.lang);
    return (
        <>
            <SignUp dictionary={data} />
        </>
    );
}

export default Page;

I can share more of the code if needed as in the code from the other components used by my page.
Answered by Cape horse mackerel
you can try to create a hook useMounted.ts
import { useEffect, useState } from "react";

/**
 * Fixes "Hydration failed because the initial UI does not match what was rendered on the server"
 * @returns {boolean} - A boolean value indicating whether the component is currently mounted.
 */
export default function useMounted(): boolean {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);

    return () => setMounted(false);
  }, []);

  return mounted;
}

give it a try
View full answer

56 Replies

Cape horse mackerel
you can try to create a hook useMounted.ts
import { useEffect, useState } from "react";

/**
 * Fixes "Hydration failed because the initial UI does not match what was rendered on the server"
 * @returns {boolean} - A boolean value indicating whether the component is currently mounted.
 */
export default function useMounted(): boolean {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);

    return () => setMounted(false);
  }, []);

  return mounted;
}

give it a try
Answer
Cape horse mackerel
usage
export default function YourComponent() {
  const mounted = useMounted();
  // ... the rest of the code

  // this should be on the last line before return
  if(!mounted) return null;
  return <div></div>
}
Sun bearOP
Oh my, I just realised something. You helped me with fixing the type error in my other thread but after updating the code it looks like I now get the same error in this page.

// app/[lang]/signup/page.tsx
"use client";
import React, { useState, ChangeEvent } from 'react';
import TopNavigationBar from '../TopNavigationBar';
import PersonalInformation from './PersonalInformation';
import type { Dictionary } from '@/app/translation/dictionaryTypes';

const SignUp = ({dictionary})=>{
    // State to manage form steps
    const [currentStep, setCurrentStep] = useState(0);

    // State to manage dictionary data
    //const [dictionary, setDictionary] = useState<Dictionary | null>(null);

    // Define the structure of your form data
    const [formData, setFormData] = useState({
        firstName: '',
        lastName: '',
        country: '',
        dateOfBirth: '',
        email: '',
        password: ''
    });

    // Handle change in form fields
    const handleChange = (event: ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
        const { name, value } = event.target;
        setFormData({ ...formData, [name]: value });
    };

    // Define the components for each step
    const steps = [
        <PersonalInformation data={formData} handleChange={handleChange} />,
        // Add other steps here as needed...
    ];

    const signUp = async (event: React.FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        // Implement sign-up logic with formData here
    };

    return (
        //UI
    );
}

export default SignUp;


Do I have to import the props here as well?
Cape horse mackerel
const SignUp = ({ dictionary }: Dictionary) => {}
@Cape horse mackerel ts const SignUp = ({ dictionary }: Dictionary) => {}
Sun bearOP
And now the other page gives errors as well
Haha 😅
If I change it back to how it was the other page doesn't give errors anymore but this page does as you can see.
So it looks like the changes we make here influence what happens on the other page
@Cape horse mackerel you can try to create a hook `useMounted.ts` ts import { useEffect, useState } from "react"; /** * Fixes "Hydration failed because the initial UI does not match what was rendered on the server" * @returns {boolean} - A boolean value indicating whether the component is currently mounted. */ export default function useMounted(): boolean { const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); return () => setMounted(false); }, []); return mounted; } give it a try
Sun bearOP
// app/[lang]/signup/page.tsx
import React from 'react';
import { getDictionary } from '@/app/translation/dictionary';
import SignUp from '@/components/SignUpProcess/page';
import type { Dictionary } from '@/app/translation/dictionaryTypes';
import useMounted from '@/hooks/useMounted';

type Props = {
  params: {
    lang: "en" | "ro";
  };
};

const Page = async (props: Props) => {
  const mounted = useMounted();
  const data = await getDictionary(props.params.lang);

  if (!mounted) return null;

  return (
    <>
      <SignUp dictionary={data} />
    </>
  );
};

export default Page;

As for the hook suggestion, I am getting this error when loading the page.
Cape horse mackerel
// page.tsx
"use client";
// ...rest of the code
const Page = () => {}

this is for the hook
@Cape horse mackerel ts // page.tsx "use client"; // ...rest of the code const Page = () => {} this is for the hook
Sun bearOP
I am already using use client for the page.tsx, the idea is for the page.tsx inside the actual signup page to stay SSR.
Cape horse mackerel
then try to use hook within SignUpProcess/page.tsx
@Cape horse mackerel then try to use hook within SignUpProcess/page.tsx
Sun bearOP
That is already what I'm doing
Haha, sorry if this is confusing
Cape horse mackerel
no, you're not
you're using hook within [lang]/signup/page.tsx
@Cape horse mackerel then try to use hook within SignUpProcess/page.tsx
Sun bearOP
Oh, my bad, I've misread that.
Cape horse mackerel
should use it within components/SignUpProcess/page.tsx
@Cape horse mackerel should use it within components/SignUpProcess/page.tsx
Sun bearOP
Wow, somehow that also fixed the other errors in regards with the dictionary.
Do you know why that is ?
No more errors in any of the pages 👀
This is the only issue left now
The page loads though
@Anay-208 | Ping in replies And here, in type Props, I recommend setting lang to string
Sun bearOP
I am getting this error again now
@Sun bear I am getting this error again now
Wait do you only support 2 languages?
If you only support 2, then change it back
@Anay-208 | Ping in replies Wait do you only support 2 languages?
Sun bearOP
Uh, I plan to support more, for now it's only 2 because I will add the rest of them at the end.
Sun bearOP
I think it makes the development a bit easier
@Anay-208 | Ping in replies Then change it back then
Sun bearOP
But why doesn't it work with 2 ?
Like what's the difference.
@Sun bear But why doesn't it work with 2 ?
It’ll work with 2, but since you only have 2, I’ll recommend that only.
You’ll have to change dictionary.tsx then
Like change the argument
Sun bearOP
// dictionary.ts
import 'server-only';
import type { Locale } from '@/i18n.config';
import type { Dictionary } from './dictionaryTypes';

const dictionaries = {
  en: () => import('./dictionaries/en.json').then(module => module.default as Dictionary),
  ro: () => import('./dictionaries/ro.json').then(module => module.default as Dictionary)
};

export const getDictionary = async (locale: Locale): Promise<Dictionary> => {
  if (!dictionaries[locale]) {
    // Return a default dictionary or one of the existing ones
    return dictionaries['en']();
  }
  return dictionaries[locale]();
};
This is my dictionary.ts file
@Anay-208 | Ping in replies Show i18n.config
Sun bearOP
//i18n.config.ts
export const i18n = {
    defaultLocale: 'en',
    locales: ['en', 'ro']
  } as const
  
  export type Locale = (typeof i18n)['locales'][number]
@Sun bear js //i18n.config.ts export const i18n = { defaultLocale: 'en', locales: ['en', 'ro'] } as const export type Locale = (typeof i18n)['locales'][number]
I’m not sure as I’m new to ts. Id prefer not to share as I don’t have complete knowledge
@Anay-208 | Ping in replies I’m not sure as I’m new to ts. Id prefer not to share as I don’t have complete knowledge
Sun bearOP
Oh okay, totally understandable. Then I will leave it as it is for now and sort it out at a later point in time.
But I appreciate you tried to help me with that as well!
Great idea.
@Anay-208 | Ping in replies And can you dm me 1 min
Sun bearOP
Of course
@Anay-208 | Ping in replies And can you dm me 1 min
Sun bearOP
It looks like it won't let me dm you, you probably do not accept messages from other people.
@Sun bear It looks like it won't let me dm you, you probably do not accept messages from other people.
Maybe it’s with you. It’s enabled in my server settings