Search code examples
reactjsreact-hooksform-datareact-hook-form

Need to get three Modal screens data using react-hook-form, tried useFormContext and not successful


I am using react-hook-form in my project for form data handling.

I have a create functionality that has three modal screens, and I need the entire three modal screens data on the third-page submission. How can I get this?

I tried useFormContext but it's retrieving me the last third modal screen data instead of the entire data.

// Parent Component
const Parent = () => {
  const [page, setPage] = useState(1);
  const nextPage = () => setPage(page + 1);
  const previousPage = () => setPage(page - 1);
  const methods = useForm();

 return (  
   <FormProvider {...methods}>
   // after submitting 3 forms, I get 3rd form data here, below line
    <form onSubmit={methods.handleSubmit(data => console.log(data))}> 
      {page === 1 && (
        <CreateOne
          nextPage={nextPage}
          cancel={cancel}
        />
      )}
      {page === 2 && (
        <CreateTwo
          previousPage={previousPage}
          nextPage={nextPage}
        />
      )}
      {page === 3 && (
        <CreateThree
          previousPage={previousPage}
          cancel={cancel}
        />
      )}
     </form>
    </FormProvider>
  );
}
const CreateOne = ({ nextPage, cancel }) => {
  const methods = useFormContext();

  return (
    <input ... ref={methods.register} />
    <input ... ref={methods.register} />
    <input ... ref={methods.register} />
    
    <Button onClick={cancel} text="cancel" />
    <Button type="submit" onClick={nextPage} text="next"/>
  );
}
const CreateOTwo = ({previousPage, nextPage}) => {
  const methods = useFormContext();

  return (
    <input ... ref={methods.register} />
    <input ... ref={methods.register} />
    <input ... ref={methods.register} />
    
    <Button onClick={previousPage} text="previousPage" />
    <Button type="submit" onClick={nextPage} text="next"/>
  );
}

const CreateOThree = ({previousPage}) => {
  const methods = useFormContext();

  return (
    <input ... ref={methods.register} />
    <input ... ref={methods.register} />
    <input ... ref={methods.register} />
    
    <Button onClick={previousPage} text="previousPage" />
    <Button type="submit" text="submit"/>
  );
}

Can anyone help me with pointers? how can I get the 3 modal screens data?


Solution

  • I solved this... Posting the answer here, so it could help others..

    // Parent Component
    const Parent = () => {
      const [page, setPage] = useState(1);
      const nextPage = () => setPage(page + 1);
      const previousPage = () => setPage(page - 1);
      const [finalObj, setFinalObj] = useState(null);
    
     useEffect(() => {
    // this if, checks and then once 3rd form form data is available, we call parent fn.
        if (page === 3) {  
          CallParentWhichTriggeredThisModal(vendor);
        }
      }, [page]); // this useEffect hook gets called for each page state change, as we passed 
     //this as the second array of parameters.
    
      const page1= (data) => {
        setFinalObj((prevState) => ({ ...prevState, ...data }));
        nextPage();
      };
    
      const page2= (data) => {
        setFinalObj((prevState) => ({ ...prevState, ...data}));
        nextPage();
      };
    
      const page3= async (data) => {
    // this setState below is an asynchronous, so if you call your parent fn, just below this, // then you might lose the 3rd page data. to fix this, we used useEffect.
        setFinalObj((prevState) => ({ ...prevState, ...data}));
      };
    
    
     return (  
       <> 
          {page === 1 && (
            <CreateOne
              nextPage={nextPage}
              cancel={cancel}
              submitForm={page1}
            />
          )}
          {page === 2 && (
            <CreateTwo
              previousPage={previousPage}
              nextPage={nextPage}
              submitForm={page2}
            />
          )}
          {page === 3 && (
            <CreateThree
              previousPage={previousPage}
              cancel={cancel}
              submitForm={page3}
            />
          )}
        </>
      );
    }
    
    const CreateOne = ({ submitForm, nextPage, cancel }) => {
      const methods = useFormContext();
      const { register, handleSubmit } = useForm();
    
      return (
     <form onSubmit={handleSubmit(submitForm)}>
        <input ... ref={register} />
        <input ... ref={register} />
        <input ... ref={register} />
        
        <Button onClick={cancel} text="cancel" />
        <Button type="submit" text="next"/>
      </form>
      );
    }
    
    const CreateOTwo = ({submitForm, previousPage, nextPage}) => {
      const methods = useFormContext();
      const { register, handleSubmit } = useForm();
    
      return (
     <form onSubmit={handleSubmit(submitForm)}>
        <input ... ref={register} />
        <input ... ref={register} />
        <input ... ref={register} />
        
        <Button onClick={cancel} text="cancel" />
        <Button type="submit" text="next"/>
      </form>
      );
    }
    
    
    const CreateOThree = ({submitForm, previousPage}) => {
      const methods = useFormContext();
      const { register, handleSubmit } = useForm();
    
      return (
     <form onSubmit={handleSubmit(submitForm)}>
        <input ... ref={register} />
        <input ... ref={register} />
        <input ... ref={register} />
        
        <Button onClick={cancel} text="cancel" />
        <Button type="submit" text="next"/>
      </form>
      );
    }