'React/JS if and for conditions
I am trying to create a form and store it in an useState array, every time there is a change on "maritalStatus" of the field and the status is 'Married' - I need to append the form so that the data I will store will store 2 persons details from the form (firstname/lastname/phone etc) if the status is other than 'Married' the data I store will only be for 1 person.
I am new to RN and I just can't handle this "IF" condition, would be glad if anyone can help.
Also in case the person selects - the children field and inputs a value( for example 2) the array should also be appended with 2 other fields and I will add later a fuction that will store this data on a remote server.
import React, { useState } from "react";
import {
Card,
CardContent,
Container,
Grid,
TextField,
FormControl,
InputLabel,
MenuItem,
Select,
FormControlLabel,
RadioGroup,
Radio,
FormLabel
} from '@mui/material';
import { Box } from '@mui/system';
function AddForm() {
const defaultData = {
firstName: '',
lastName:'',
email:'',
childrens:'',
gender:'Male',
participation:'Yes',
phone1:'',
phone2:'',
phone3:'',
maritalStatus:'',
}
const [applicant, setApplicant] = useState([{ ...defaultData }]);
const onChange = (e, index) => {
const { name, value } = e.target;
const data = [...applicant];
data[index][name] = value;
setApplicant(data);
};
const onChildrensChange = (e, index) => {
const { name, value } = e.target;
const data = [...applicant];
data[index][name] = value;
setApplicant(data)
setApplicant([...applicant, { ...defaultData }]);
};
let onMaritalStatusChange = (e, index) => {
const { name, value } = e.target;
const data = [...applicant];
data[index][name] = value;
setApplicant(data)
if(e.maritalStatus === 'Married'){
setApplicant([...applicant, { ...defaultData }]);
}
};
const onAddClick = () => {
setApplicant([...applicant, { ...defaultData }]);
};
return (
<Container>
<Card>
<CardContent>
{applicant.map((element, index) => {
return (
<Grid>
<Grid>
<TextField
label="First Name"
name="firstName"
value={element.firstName}
onChange={(e) => onChange(e, index)}
fullWidth
/>
<TextField
label="Last name"
name="lastName"
value={element.lastName}
onChange={(e) => onChange(e, index)}
fullWidth
/>
<TextField
label="Email"
name="email"
value={element.email}
onChange={(e) => onChange(e, index)}
fullWidth
/>
<TextField
label="childrens"
name="childrens"
value={element.childrens}
onChange={(e) => onChildrensChange(e, index)}
fullWidth
/>
<FormControl fullWidth>
<InputLabel>Gender</InputLabel>
<Select
label="gender"
name='gender'
fullWidth
onChange={(e) => onChange(e, index)}
defaultValue='Male'
>
<MenuItem value={'Male'}>Male</MenuItem>
<MenuItem value={'Female'}>Female</MenuItem>
</Select>
</FormControl>
<FormControl fullWidth>
<InputLabel>Marital Status</InputLabel>
<Select
label="maritalStatus"
name='maritalStatus'
fullWidth
onChange={(e) => onMaritalStatusChange(e, index)}
defaultValue='Single'
>
<MenuItem value={'SINGLE'}>Single</MenuItem>
<MenuItem value={'Married'}>Married</MenuItem>
<MenuItem value={'Divorced'}>Divorced</MenuItem>
<MenuItem value={'Widowed'}>Widowed</MenuItem>
</Select>
</FormControl>
<FormControl>
<FormLabel>Participation</FormLabel>
<RadioGroup
defaultValue="female"
name="participation"
onChange={(e) => onChange(e, index)}
>
<FormControlLabel value="Yes" control={<Radio />} label="Yes" />
<FormControlLabel value="No" control={<Radio />} label="No" />
</RadioGroup>
</FormControl>
<TextField
label="Phone"
name="phone1"
value={element.phone1}
onChange={(e) => onChange(e, index)}
fullWidth
/>
<TextField
label="Phone"
name="phone2"
value={element.phone2}
onChange={(e) => onChange(e, index)}
fullWidth
/>
<TextField
label="Phone"
name="phone3"
value={element.phone3}
onChange={(e) => onChange(e, index)}
fullWidth
/>
</Grid>
</Grid>
)
})}
<Box mt={5}>{JSON.stringify(applicant)}</Box>
</CardContent>
</Card>
</Container>
)
}
export default AddForm;
import './App.css';
import AddForm from './AddForm';
function App() {
return (
<div className="App">
<AddForm/>
</div>
);
}
export default App;
Solution 1:[1]
Define a key like "spouse" with object type value on defaultData object. Have the spouse form details defined just beneath the "maritalStatus" select dropdown. Use conditional rendering for spouse form like below
{ element.maritalStatus === "Married" && (
// write the spouse form here
)}
So, as soon as you update the state with maritalStatus and it is "Married", the spouse form details would be rendered.
You can do the same for children forms too.
Solution 2:[2]
You are checking e. maritalStatus. Instead you should check e.target.value or, in your case, as you are already destructuring the value, you can directly check the value
if(value==="Married"){ // write your code over here}
Also to solve this problem you need to play with the Applicant state where on the basis of children and married you can show the form.
const Myform = () => {
const defaultData = {
firstName: "",
lastName: "",
email: "",
childrens: "",
gender: "Male",
participation: "Yes",
phone1: "",
phone2: "",
phone3: "",
maritalStatus: ""
};
const [applicant, setApplicant] = React.useState(defaultData);
const handleChildern = (e) => {
const udatedApplicant = { ...applicant };
udatedApplicant.childrens = e.target.value;
setApplicant({ ...udatedApplicant });
};
const handleRadio = (e) => {
const udatedApplicant = { ...applicant };
udatedApplicant.maritalStatus = e.target.value;
setApplicant({ ...udatedApplicant });
};
return (
<>
<div onChange={handleRadio}>
<label htmlFor="Married">Married</label>
<input type="radio" id="Married" name="marStatus" value="Married" />
<label htmlFor="single">Single</label>
<input type="radio" id="single" name="marStatus" value="Single" />
</div>
<div>
<label htmlFor="children">children</label>
<input type="text" id="children" onChange={handleChildern} />
</div>
{applicant.maritalStatus === "Married" && <RenderSpouse />}
{Number(applicant.childrens) > 0 && (
<RenderChildren numberOfChildren={applicant.childrens} />
)}
</>
);
};
const RenderSpouse = () => {
return <div>Hi I am spouse</div>;
};
const RenderChildren = ({ numberOfChildren }) => {
const [childrens, setChildrens] = React.useState(
new Array(Number(numberOfChildren)).fill("")
);
useEffect(() => {
const newChildren = new Array(Number(numberOfChildren)).fill("");
setChildrens(newChildren);
}, [numberOfChildren]);
return (
<>
{childrens.map((_, index) => {
return <div key={index}>children {index}</div>;
})}
</>
);
};
So with this approach your form would be more generic to solve this problem
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dharman |
| Solution 2 |
