How can I fix these 3 Hydration Errors ?
Answered
Sun bear posted this in #help-forum
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
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.
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191466833556033616/Screenshot_at_Jan_01_21-20-41.png?ex=65a58af5&is=659315f5&hm=32d08f5747d02d9e30553109281f4d2dcba4948e7bdf986c237ca8d1262b6ff4&)
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191466834000621658/Screenshot_at_Jan_01_21-20-55.png?ex=65a58af5&is=659315f5&hm=81b0c3ae6949446b98a5025094ccbf63586550c0589af7dc13228bc36fcde5e1&)
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191466834378100796/Screenshot_at_Jan_01_21-21-01.png?ex=65a58af5&is=659315f5&hm=9436f91f40c4e934763907cb1b429f85efb8fd75e46a821598d2afa757b5bca5&)
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
![Avatar](https://cdn.discordapp.com/embed/avatars/2.png)
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
![Avatar](https://cdn.discordapp.com/embed/avatars/2.png)
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>
}
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
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?
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191468530357514270/Screenshot_at_Jan_01_21-50-27.png?ex=65a58c8a&is=6593178a&hm=e974e01156ebf7f75129bf0af9d835c083c8e5eeac9dc75d248e098222f1bb07&)
![Avatar](https://cdn.discordapp.com/embed/avatars/2.png)
Cape horse mackerel
const SignUp = ({ dictionary }: Dictionary) => {}
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191468876257562735/Screenshot_at_Jan_01_21-51-50.png?ex=65a58cdc&is=659317dc&hm=95865ac00a8c9714e4029d1efef812d24b540358589aaa99cc9c809c2a47f099&)
And now the other page gives errors as well
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191469286754103346/Screenshot_at_Jan_01_21-53-24.png?ex=65a58d3e&is=6593183e&hm=fd5a8223436f884ad01215ce8be9efb3eb5ffc099fc22a6196fcc898c29e1600&)
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.
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191469770537705595/Screenshot_at_Jan_01_21-55-10.png?ex=65a58db1&is=659318b1&hm=5982b471101510a2bc3a5570cfa2e2770635625a308db34e21d40c5cf498eacc&)
So it looks like the changes we make here influence what happens on the other page
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191470044639662200/Screenshot_at_Jan_01_21-56-27.png?ex=65a58df3&is=659318f3&hm=2af364d7b377dc0cac1218f8eb829e568aab46fe369e12362480c4188c6cdb20&)
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
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.
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191472125165453332/Screenshot_at_Jan_01_22-04-20.png?ex=65a58fe3&is=65931ae3&hm=63e5e22f6c95e9259d12de78be82e7fddabfcbf23a777d65345ccb0d8662e11e&)
![Avatar](https://cdn.discordapp.com/embed/avatars/2.png)
Cape horse mackerel
// page.tsx
"use client";
// ...rest of the code
const Page = () => {}
this is for the hook
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191473881622524004/Screenshot_at_Jan_01_22-11-39.png?ex=65a59185&is=65931c85&hm=25782da51c22fc03bbdf908e5dc3d6604fb06e5a8b342f0b6bc61be881624885&)
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.
![Avatar](https://cdn.discordapp.com/embed/avatars/2.png)
Cape horse mackerel
then try to use hook within SignUpProcess/page.tsx
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
That is already what I'm doing
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191474268144414770/Screenshot_at_Jan_01_22-13-12.png?ex=65a591e2&is=65931ce2&hm=724f5ac0a0ce0061591ba6c75e1f36f8fe571b2534cde29e1c9edc246544d15a&)
Haha, sorry if this is confusing
![Avatar](https://cdn.discordapp.com/embed/avatars/2.png)
Cape horse mackerel
no, you're not
you're using hook within [lang]/signup/page.tsx
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
Oh, my bad, I've misread that.
![Avatar](https://cdn.discordapp.com/embed/avatars/2.png)
Cape horse mackerel
should use it within components/SignUpProcess/page.tsx
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
Wow, somehow that also fixed the other errors in regards with the dictionary.
Do you know why that is ?
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191475599353577492/Screenshot_at_Jan_01_22-18-32.png?ex=65a5931f&is=65931e1f&hm=b55dbf0f557f9ea2175b09e14e102e150eaeb3a0d130f413172f49630795df2d&)
No more errors in any of the pages 👀
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191476002229072052/Screenshot_at_Jan_01_22-20-04.png?ex=65a5937f&is=65931e7f&hm=ff9663fb326e94c9e791c23b30457fa016af896607179634691bb1510389e037&)
This is the only issue left now
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191476258878537819/Screenshot_at_Jan_01_22-20-57.png?ex=65a593bc&is=65931ebc&hm=a6c148817d30c016d66e87e86f4ff65c54e478de51d9ecae2e1fd457ccbb28b3&)
The page loads though
![Avatar](https://cdn.discordapp.com/avatars/755810867878297610/5ab9ece60bc14c554a7376a599d3deb3.webp?size=256)
Ping me for help
And here, in type Props, I recommend setting lang to string
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
I am getting this error again now
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191478654681755750/Screenshot_at_Jan_01_22-30-34.png?ex=65a595f7&is=659320f7&hm=766d9089432dea635e1f54ca14b2a67517eae96f2e18a90dc10cea638d4ba2a9&)
![Image](https://cdn.discordapp.com/attachments/1191466833107226654/1191479015949738084/Screenshot_at_Jan_01_22-32-06.png?ex=65a5964e&is=6593214e&hm=496b6564b22ae4be0ac5cf9ad2246b03a8df8e945b046714074a6f671a045619&)
![Avatar](https://cdn.discordapp.com/avatars/755810867878297610/5ab9ece60bc14c554a7376a599d3deb3.webp?size=256)
Ping me for help
Wait do you only support 2 languages?
If you only support 2, then change it back
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
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.
![Avatar](https://cdn.discordapp.com/avatars/755810867878297610/5ab9ece60bc14c554a7376a599d3deb3.webp?size=256)
Ping me for help
Then change it back then
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
I think it makes the development a bit easier
But why doesn't it work with 2 ?
Like what's the difference.
![Avatar](https://cdn.discordapp.com/avatars/755810867878297610/5ab9ece60bc14c554a7376a599d3deb3.webp?size=256)
Ping me for help
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
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
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
![Avatar](https://cdn.discordapp.com/avatars/755810867878297610/5ab9ece60bc14c554a7376a599d3deb3.webp?size=256)
Ping me for help
Show i18n.config
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
//i18n.config.ts
export const i18n = {
defaultLocale: 'en',
locales: ['en', 'ro']
} as const
export type Locale = (typeof i18n)['locales'][number]
![Avatar](https://cdn.discordapp.com/avatars/755810867878297610/5ab9ece60bc14c554a7376a599d3deb3.webp?size=256)
Ping me for help
I’m not sure as I’m new to ts. Id prefer not to share as I don’t have complete knowledge
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
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!
![Avatar](https://cdn.discordapp.com/avatars/755810867878297610/5ab9ece60bc14c554a7376a599d3deb3.webp?size=256)
Ping me for help
Great idea.
No problem
And can you dm me 1 min
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
Of course
It looks like it won't let me dm you, you probably do not accept messages from other people.
![Avatar](https://cdn.discordapp.com/avatars/755810867878297610/5ab9ece60bc14c554a7376a599d3deb3.webp?size=256)
Ping me for help
Maybe it’s with you. It’s enabled in my server settings
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Sun bearOP
Yup, that was it.