How can I fix these 3 Hydration Errors ?
Answered
Sun bear posted this in #help-forum

Sun bearOP
Here is my code:
I can share more of the code if needed as in the code from the other components used by my page.
//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
give it a try
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
56 Replies

Cape horse mackerel
you can try to create a hook
give it a try
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.
Do I have to import the props here as well?
// 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) => {}
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
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 on 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 on 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 on 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 on 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 on 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 on replies And can you dm me 1 min

Sun bearOP
Of course

@Anay-208 | Ping on 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

@Anay-208 | Ping on replies Maybe it’s with you. It’s enabled in my server settings

Sun bearOP
Yup, that was it.