Next.js Discord

Discord Forum

Multi-Form Sign-up - Errors Implementing

Answered
Sun bear posted this in #help-forum
Open in Discord
Sun bearOP
I am getting this error after trying to import my Step 1 Component into my signup page (which I turned into a client page)

Here is my code:
// app/[lang]/signup/page.tsx
"use client";
import React, { useState, useEffect, ChangeEvent } from 'react';
import TopNavigationBar from '../../../components/TopNavigationBar';
import PersonalInformation from '../../../components/SignUpProcess/PersonalInformation';
import { Locale } from '@/i18n.config';
import type { Dictionary } from '@/app/translation/dictionaryTypes';
import { getDictionary } from '@/app/translation/dictionary';

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

  // State to manage dictionary data
  const [dictionary, setDictionary] = useState<Dictionary | null>(null);
  const [lang, setLang] = useState<Locale>('en'); // Default language

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

  useEffect(() => {
    async function fetchData() {
      try {
        const fetchedDictionary = await getDictionary(lang);
        setDictionary(fetchedDictionary);
      } catch (error) {
        console.error('Error fetching dictionary:', error);
      }
    }

    fetchData();
  }, [lang]);

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

  const steps = [
    <PersonalInformation data={formData} handleChange={handleChange} />,
    // Other Steps will go here
  ];

  const signUp = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    
  };

  // Check if dictionary data is loaded
  if (!dictionary) {
    return <div>Loading...</div>;
  }

  return (
// UI
}

export default SignUp;
Answered by Anay-208
First:
- create a new file(a component)
- move all the code of signup/page.tsx to that new file
- in the page.tsx, which would be a use server component, import this
import { getDictionary } from '@/app/translation/dictionary';

and remove it from client component
- In client component add a props for data
- in server component, which would be like this:
import { getDictionary } from '@/app/translation/dictionary';
import SignUp from "./_components/page.tsx" // 
const Page = () => {
const data = await getDictionary()
return(
<>
<SignUp fetchedDictionary={fetchedDictionary} />
</>
)
}

now remove that that useEffect hook
View full answer

121 Replies

@Sun bear I am getting this error after trying to import my Step 1 Component into my signup page (which I turned into a client page) Here is my code: js // app/[lang]/signup/page.tsx "use client"; import React, { useState, useEffect, ChangeEvent } from 'react'; import TopNavigationBar from '../../../components/TopNavigationBar'; import PersonalInformation from '../../../components/SignUpProcess/PersonalInformation'; import { Locale } from '@/i18n.config'; import type { Dictionary } from '@/app/translation/dictionaryTypes'; import { getDictionary } from '@/app/translation/dictionary'; const SignUp = () => { // State to manage form steps const [currentStep, setCurrentStep] = useState(0); // State to manage dictionary data const [dictionary, setDictionary] = useState<Dictionary | null>(null); const [lang, setLang] = useState<Locale>('en'); // Default language // Structure of my form data const [formData, setFormData] = useState({ firstName: '', lastName: '', country: '', dateOfBirth: '', email: '', password: '' }); useEffect(() => { async function fetchData() { try { const fetchedDictionary = await getDictionary(lang); setDictionary(fetchedDictionary); } catch (error) { console.error('Error fetching dictionary:', error); } } fetchData(); }, [lang]); // Handle change in form fields const handleChange = (event: ChangeEvent<HTMLInputElement | HTMLSelectElement>) => { const { name, value } = event.target; setFormData({ ...formData, [name]: value }); }; const steps = [ <PersonalInformation data={formData} handleChange={handleChange} />, // Other Steps will go here ]; const signUp = async (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); }; // Check if dictionary data is loaded if (!dictionary) { return <div>Loading...</div>; } return ( // UI } export default SignUp;
You have to use server component with one of the imported package.
@Anay-208 You have to use server component with one of the imported package.
Sun bearOP
Well that's actually my question cause you see my login page is a server page right, and thing is that these two files that the error is complaining about:
// 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]();
};


Are server (SSR) components because Initially both login and signup pages were server pages, but because I need my signup page to be multi-form, from what I understand that can only be done by making it a client page instead.

So what would you suggest I need to do in this situation ? Which page/component should I turn into a client component and what should stay server ?
@Sun bear I am getting this error after trying to import my Step 1 Component into my signup page (which I turned into a client page) Here is my code: js // app/[lang]/signup/page.tsx "use client"; import React, { useState, useEffect, ChangeEvent } from 'react'; import TopNavigationBar from '../../../components/TopNavigationBar'; import PersonalInformation from '../../../components/SignUpProcess/PersonalInformation'; import { Locale } from '@/i18n.config'; import type { Dictionary } from '@/app/translation/dictionaryTypes'; import { getDictionary } from '@/app/translation/dictionary'; const SignUp = () => { // State to manage form steps const [currentStep, setCurrentStep] = useState(0); // State to manage dictionary data const [dictionary, setDictionary] = useState<Dictionary | null>(null); const [lang, setLang] = useState<Locale>('en'); // Default language // Structure of my form data const [formData, setFormData] = useState({ firstName: '', lastName: '', country: '', dateOfBirth: '', email: '', password: '' }); useEffect(() => { async function fetchData() { try { const fetchedDictionary = await getDictionary(lang); setDictionary(fetchedDictionary); } catch (error) { console.error('Error fetching dictionary:', error); } } fetchData(); }, [lang]); // Handle change in form fields const handleChange = (event: ChangeEvent<HTMLInputElement | HTMLSelectElement>) => { const { name, value } = event.target; setFormData({ ...formData, [name]: value }); }; const steps = [ <PersonalInformation data={formData} handleChange={handleChange} />, // Other Steps will go here ]; const signUp = async (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); }; // Check if dictionary data is loaded if (!dictionary) { return <div>Loading...</div>; } return ( // UI } export default SignUp;
If you see at the top. There is use client
@Anay-208 If you see at the top. There is use client
Sun bearOP
Affirmative, I see that.
Do I need to move that someplace else or do I need to import one of the components as a server component implicitly ?
Sun bearOP
Which in my case would be dictionary.ts right ?
@Anay-208 Yup
Sun bearOP
And how do I do that ?
@Sun bear And how do I do that ?
Use getdectionary in server side and pass the info to client side
@Anay-208 Use getdectionary in server side and pass the info to client side
Sun bearOP
Do I have to use API routes or can it be done in a simpler way ?
You don’t need api routes. Can you send your use server component code?
server.ts ?
@Sun bear Which component exactly ?
I’ll give you instructions in a little while
Sun bearOP
Awesome, I'll wait
Happy new year by the way! 🥂
You've a function called fetchData
    async function fetchData() {
      try {
        const fetchedDictionary = await getDictionary(lang);
        setDictionary(fetchedDictionary);
      } catch (error) {
        console.error('Error fetching dictionary:', error);
      }

Use this function in useServer component. And modify the component like this:
const data = await getDirectionary(lang)
return(
<>
<Component data={data}/ >
</>
)
you must have understood now
@Sun bear Uh, I don't actually. Where am I supposed to use the second snippet, is it in dictionary.ts ?
I've just given an example, on how to fix. You basically have to use the dictionary.tsx in a server component. and whatever data you get from it, pass it to client component
@Anay-208 I've just given an example, on how to fix. You basically have to use the dictionary.tsx in a server component. and whatever data you get from it, pass it to client component
Sun bearOP
So I need to make my signup page a server component again, but then how do I import the PersonalInformation component which is a client one ? And how do I switch between layouts without using Use Effect ?

The reason I made the signup page client was so that I can use the Use Effect to switch between the signup steps.
First:
- create a new file(a component)
- move all the code of signup/page.tsx to that new file
- in the page.tsx, which would be a use server component, import this
import { getDictionary } from '@/app/translation/dictionary';

and remove it from client component
- In client component add a props for data
- in server component, which would be like this:
import { getDictionary } from '@/app/translation/dictionary';
import SignUp from "./_components/page.tsx" // 
const Page = () => {
const data = await getDictionary()
return(
<>
<SignUp fetchedDictionary={fetchedDictionary} />
</>
)
}

now remove that that useEffect hook
Answer
Sun bearOP
Basically this is how (I THINK) the page is supposed to be split like. The component in the middle is basically the Step component so that means that when the user presses continue it will be replaced with the next step (the next component, in my case AccountDetails.tsx) and so on.

The component at the top (the stepper) is another client component but that one would be sort of static (as in it will be present on the page throughout most of the signup process), and it's the same with the buttons at the bottom with the only difference being that they would be part of the server component I think. At least that's how I think it would have to work in code.
@Sun bear I have followed the instructions you gave me and I am getting this error.
oh 1 min, edit it to
const Page = ({params}) => {
const data = await getDictionary(params.lang)
...rest of the code
Or just use this first:
const Page = (props) => {
console.log(props)
...

and see in which property you get the value of query lang
@Anay-208 oh 1 min, edit it to ts const Page = ({params}) => { const data = await getDictionary(params.lang) ...rest of the code
Sun bearOP
@Sun bear Click to see attachment
I'll guide you in fixing the warnings later on.
just edit the function to this
const Page = (props) => {
console.log(props)
const data = await getDictionary(props.query.lang)
...

just see if it works, and send me screenshot of console
Sun bearOP
"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 = () => {
    // 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
    };

    // Check if dictionary data is loaded
    if (!dictionary) {
        return <div>Loading...</div>;
    }

    return (
//UI
);
}

export default SignUp;
@Anay-208 also remove useState for lang
Sun bearOP
I've updated it, please let me know if it's good to go now
@Sun bear I've updated it, please let me know if it's good to go now
try to run the code. there is a chance you may see a error
or run the app
@Anay-208 try to run the code. there is a chance you may see a error
Sun bearOP
I can't run it because I have errors
@Sun bear I can't run it because I have errors
const Page = async (props) =>
change it to this
I'll guide you on fixing all the warnings later on
Sun bearOP
Hmm, I think I get the same warning when loading the page
Sun bearOP
@Anay-208 your code isn't saved
Sun bearOP
You were right, the error above popped up instead. I had to restart the server to make sure the code is updated.
Also I'm so sorry to take from your time, it's just that I've never done this and as you can see it's complicated to implement this multi step signup functionality, especially for a beginner.
And in the terminal I get this
@Sun bear Hmm, I think I get the same warning when loading the page
at the bottom also add
export default Page;
its much better to hire a freelancer for this stuff actually. I didn't specify most of the stuff because I expected you to know javascript.
in the future, you'll atleast have to hire someone(like me) to help and teach you stuff whenever you face some errors, or another option is to learn from a online course or yt
@Anay-208 at the bottom also add tsx export default Page;
Sun bearOP
@Sun bear Click to see attachment
check the console, and send screenshot
I expected a similar error only
@Anay-208 its much better to hire a freelancer for this stuff actually. I didn't specify most of the stuff because I expected you to know javascript.
Sun bearOP
Trust me if I had the possibility to hire one I would've done it on spot, it's very frustrating to have to deal with this stuff but I don't have the possibility to hire one at the moment so I try and seek help where I get stucked and luckily there are people kind enough to offer their help like you do here and there, which is a life saver.
@Anay-208 check the console, and send screenshot
Sun bearOP
Here it is
@Sun bear Here it is
send full console screenshot. there must be a object printed
@Anay-208 send full console screenshot. there must be a object printed
Sun bearOP
@Sun bear Click to see attachment
change the argument of function to props.params.lang
@Anay-208 change the argument of function to props.params.lang
Sun bearOP
Now the signup page says Loading..
And the console
@Sun bear Now the signup page says Loading..
send screenshot of code from SignIn component
dont send it as a message. its much easier to see vscodes formatting
@Anay-208 send screenshot of code from SignIn component
Sun bearOP
@Sun bear Click to see attachment
Remove line 13
Set line 8 to
const SignUp = ({dictionary}){

Remove line 43 to 45


In the file page.tsx (server component),
set line 9to:
<SignUp dictionary={data} />
@Anay-208 Remove line 13 Set line 8 to ts const SignUp = ({dictionary}){ Remove line 43 to 45 In the file page.tsx (server component), set line 9to: <SignUp dictionary={data} />
Sun bearOP
This created an error in the client page
But, it looks like there's only one error left now in the server component
@Sun bear This created an error in the client page
this you see, is a warning, I'll guide you on how to fix it
Is the code working fine?
in the browser
Sun bearOP
Uh, the page still says "Loading..."
Just like before
did you remove this line?
maybe restart the server
@Anay-208 did you remove this line?
Sun bearOP
I did not remove that line, I'll remove it now and restart.
Sun bearOP
If I remove that it gives me a formatting error
Am I supposed to remove the entire function ?
And it gives the same error if I remove the whole function
And if i do what it says it gives me another error.
@Sun bear Click to see attachment
Before {, add =>
@Anay-208 Before `{`, add `=>`
Sun bearOP
That fixed it, however now I get another error when loading the page
And I removed the whole function just for you to know
// Check if dictionary data is loaded
    if (!dictionary) {
        return <div>Loading...</div>;
    }
I removed that part.
That’s most likely a problem of dictionary.tsx. Have you checked if it was working fine before?
Sun bearOP
Yes, it was working fine before, in fact I can test it and show you.
I will load the login page
in signin/page.tsx,
add this line before returning:
console.log(data)
Sun bearOP
I can show the code of my login page if you want to see it, in the login page the dictionary thing is working as you saw.
@Anay-208 add this line before returning: js console.log(data)
Sun bearOP
Huh, this is weird.
After adding that this is what I see when I load the page
try restarting app
@Anay-208 try restarting app
Sun bearOP
After restarting the server / app
@Sun bear After restarting the server / app
yup, everything is fine. I think the page should load without any errors. remove console.log statements from it
is the page loading fine
Sun bearOP
@Anay-208 is the page loading fine
Sun bearOP
But I still get an error in the code as you can see and 3 errors on the page and it also says it's switched to client rendering
Like I am getting hydration errors and the props parameter says that it has 'any' type and it's showed as an error.
@Sun bear But I still get an error in the code as you can see and 3 errors on the page and it also says it's switched to client rendering
@Sun bear create a different help-forum for it. Someone else will help you. Make sure the title is the error. And also, mark my message as a solution
Sun bearOP
Definitely! Thank you very much for helping me load the page
By the way if you need help with mock-ups or design in general I am a designer just dm me and I will help you as well.