-1

If I create a single page form and try to create a business it works but it doesn't when I try to do the same in a multi step form. I can see the data from each form but it just doesn't submit successfully for some reason. I'm using Redux toolkit to store the data in an organizationReducer. What could I be doing wrong? Am I to create a separate for each form?

import Stepper from "./components/Stepper";
import Account from "./components/steps/Account";
import Details from "./components/steps/Details";
import Payment from "./components/steps/Payment";
import { useDispatch, useSelector} from "react-redux";
import { useNavigate } from "react-router-dom";
import { createOrganization} from "../../../features/organization/organizationSlice";

const Onboarding = () => {

    const [step, setStep] = useState(0);

    const steps = ["", "", "", ];

    const navigate = useNavigate();
    const dispatch = useDispatch();

    const { isError, isSuccess, message } = useSelector((state) =>state.organization);

    const [formData, setFormData] = useState({
      businessName: "",
      businessEmail: "",
      currency: "",
      industry: "",
      businessDescription: "",
      useCase: "",
      organizationType: "",
      website: "",
      businessPhone: "",
      country: "",
      billingName: "",
      billingEmail: "",
      addressState: "",
      addressCity: "",
      addressStreet: ""
    });

    const displayStep = () => {
     switch (step) {
      case 0:
       return <Account formData = {formData} setFormData ={setFormData}/>;
       case 1:
       return <Details formData = { formData} setFormData ={setFormData}/>;
       case 2:
       return <Payment formData = { formData } setFormData ={setFormData}/>;
      }
    };

    const handleSubmit = () => {
      if (step === 0) {
        if (formData.businessName === '') {
          toast({
            title: 'Error',
            description: ('Please provide a business name'),
            status: 'error',
            position: 'top-right',
            duration: 3000,
            isClosable: true,
          })
        } else {
          setStep(step + 1);
        }

      } else if (step === 1) {
        if (formData.website === '') {
          toast({
            title: 'Error',
            description: ('Please provide a website'),
            status: 'error',
            position: 'top-right',
            duration: 3000,
            isClosable: true,
          })
        } else {
          setStep(step + 1);
        }
      } else if (step === 2) {
        if (formData.billingName === '') {
          toast({
            title: 'Error',
            description: ('Please provide a billing name'),
            status: 'error',
            position: 'top-right',
            duration: 3000,
            isClosable: true,
          })
        } else {
          dispatch(createOrganization(formData))

        }
      }

    };

    return ( 
    <> 
    { /* Stepper */ } 
     < Stepper steps = {steps} step = {step} /> > 
      {displayStep()} 
      <Flex>
       <Box> 
       {step > 0 && <Button onClick = {() => setStep(step - 1)}>Back< /Button>} 
       </Box> <
        Spacer / >
        <Box>
        <Button onClick = {handleSubmit}> 
        {step === 0 || step === 1 ? "Next" : "Submit"} 
        </Button>

This is one of the forms and they pretty much all look like this

import { Center, Heading, Box, FormLabel, Select, Input, Text } from "@chakra-ui/react";

export default function Account({ formData, setFormData }) {

  return (
    <div>
      <Box w="100%" mb={4}>
        <FormLabel ml={2} fontWeight="bold" fontSize="15px">
          Business Name
        </FormLabel>
        <Center>
        <Input
          w="500px"
          fontSize="14"
          name="businessName"
          onChange={(e) => {setFormData({...formData,businessName: e.target.value,});
          }}
          value={formData.businessName}
          type="name"
        />
        </Center>
      </Box>
      <Box w="100%" mb={4}>
        <FormLabel ml={2} fontWeight="bold" fontSize="15px">
          Business Email
        </FormLabel>
        <Center>
        <Input
          w="500px"
          fontSize="14"
          name="businessEmail"
          onChange={(e) => {
            setFormData({
              ...formData,
              businessEmail: e.target.value,
            });
          }}
          value={formData.businessEmail}
          type="email"
        />
        </Center>
      </Box>
      <Box w="100%" mb={4}>
        <FormLabel ml={2} fontWeight="bold" fontSize="15px">
          Currency
        </FormLabel>
        <Center>
        <Select
          w="500px"
          fontSize="14"
          placeholder="Select option"
          onChange={(e) => {
            setFormData({
              ...formData,
              currency: e.target.value,
            });
          }}
          value={formData.currency}
          name="currency"
        >
          <option value="founder">USD</option>
          <option value="engineer">Naira</option>
          <option value="engineer">Pounds</option>
          <option value="engineer">Yen</option>
          <option value="engineer">Euros</option>
          <option value="engineer">Cedis</option>
        </Select>
        </Center>
      </Box>
      <Box w="100%" mb={4}>
        <FormLabel ml={2} fontWeight="bold" fontSize="15px">
          Industry
        </FormLabel>
        <Center>
        <Select
          w="500px"
          fontSize="14"
          placeholder="Select option"
          onChange={(e) => {
            setFormData({
              ...formData,
              industry: e.target.value,
            });
          }}
          value={formData.industry}
          name="industry"
        >
          <option value="founder">Blockchain</option>
          <option value="engineer">Engineering</option>
          <option value="engineer">Fintech</option>
        </Select>
        </Center>
      </Box>
      <Box w="100%" mb={4}>
        <FormLabel ml={2} fontWeight="bold" fontSize="15px">
          Business Description
        </FormLabel>
        <Center>
        <Input
          w="500px"
          fontSize="14"
          name="businessDescription"
          onChange={(e) => {
            setFormData({
              ...formData,
              businessDescription: e.target.value,
            });
          }}
          value={formData.businessDescription}
          type="text"
        />
        </Center>
      </Box>
      <Box w="100%" mb={4}>
        <FormLabel ml={2} fontWeight="bold" fontSize="15px">
          Use Case
        </FormLabel>
        <Center>
        <Input
          w="500px"
          fontSize="14"
          name="useCase"
          onChange={(e) => {
            setFormData({
              ...formData,
              useCase: e.target.value,
            });
          }}
          value={formData.useCase}
          type="text"
        />
        </Center>
      </Box>
    </div>
  );
}

store.js

import organizationReducer from "../features/organization/organizationSlice";

export const store = configureStore({
  reducer: {
    organization: organizationReducer
  },
});
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
karina
  • 19
  • 2

1 Answers1

0

so you can wrap all of your form controls into single Form, then instead of not showing those forms based on active step just show hide them so they can be tracked by form, finally you need just to trigger submit form and it gives you all data something like this:

    const displayStep = () => {
    return <>
            <Account hidden={step!==0} formData = {formData} setFormData ={setFormData}/>
            <Details  hidden={step!==1} formData = { formData} setFormData ={setFormData}/>
            <Payment  hidden={step!==2} formData = { formData } setFormData ={setFormData}/>
           </>
          }
        };

...
return <form onSubmit={(e)=>console.log(e.target)}>
{displayStep()}
    </form>

refer to this for getting values: here

you must have hidden props on all of step comps and use it like below:

<SomeStep hidden={hidden}...