I am trying to do a multistep form, with a final form summarizing information that the user wrote in previous steps before they can submit.
But when I write into inputs, it doesn’t display anything even if the console returns characters.
Here is a link where I reproduced the issue.
What am I doing wrong, is there a better way to do that?
>Solution :
Here is working example.
First of all you need to store your formData
in state using useState
hook. You are using global variable and React wouldn’t re-render the UI unless components props
or state
.
const [formData, setFormData] = useState({
form1: {}
form2: {}
});
Then you need to change the state, I would like to use single function for every form state.
const onChange = (formName, fieldName, value) => {
setFormData(oldFormData => ({...oldFormData, [formName]: { ...oldFormData[formName], [fieldName]: value}}))
}
Then, PaymentForm
component would be something like this.
import React from "react";
const PaymentForm = () => {
const [step, setStep] = useState(0);
const [formData, setFormData] = useState({
form1: {},
form1: {},
});
const onChange = (formName, fieldName, value) => {
setFormData((oldFormData) => ({
...oldFormData,
[formName]: { ...oldFormData[formName], [fieldName]: value },
}));
};
const onSubmit = () => {
console.log(formData);
};
return (
<div>
{step === 1 ? (
<Form1 formData={formData.form1} onChange={onChange} />
) : step === 2 ? (
<Form2 formData={formData.form2} onChange={onChange} />
) : step === 3 ? (
<Form3 formData={formData.form3} onChange={onChange} />
) : (
<Form4 formData={formData.form4} onChange={onChange} />
)}
</div>
);
};
Then use onChange
function according to your form components like below.
const Form1 = ({ formData, onChange }) => {
return (
<Flex direction="column" p={6} pb={0}>
<Heading w="100%" size="md" fontWeight="bold" mb="2%">
Customer
</Heading>
<Flex>
<FormControl isRequired>
<FormLabel htmlFor="email" fontWeight="normal">
Email address
</FormLabel>
<Input
id="email"
type="email"
value={formData.form1.email}
onChange={(e) => onChange("form1",e.target.name, e.target.value)}
/>
</FormControl>
</Flex>
</Flex>
);
};