React Country Region Select - reactjs

I have some code about react-country-region-selector, which is suppose to allow me to select the countries and regions, but countries do not get selected and regions remains a dash. Can someone tell me what went wrong with my code?
P.s I am using this site for my code, https://github.com/country-regions/react-country-region-selector
import { CountryDropdown, RegionDropdown } from 'react-country-region-selector';
import React, { useState } from "react";
const Locations = () => {
const [state, setState] = useState({
country: "",
region: ""
})
const selectCountry = (val) => {
setState({ state: val });
}
const selectRegion = (val) =>{
setState({ state: val });
}
const { country, region } = setState;
return(
<div>
<CountryDropdown
value={country}
onChange={(val) => selectCountry(val)} />
<RegionDropdown
country={country}
value={region}
onChange={(val) => selectRegion(val)} />
</div>
</div>
);
}
return default Locations;
What I currently have:
What I Need:

You just need to do some minor changes.
const selectCountry = (val) => {
setState({ country: val });
}
const selectRegion = (val) =>{
setState({ region: val });
}
const { country, region } = state;
return(
<div>
<CountryDropdown
value={country}
onChange={(val) => selectCountry(val)} />
<RegionDropdown
country={country}
value={region}
onChange={(val) => selectRegion(val)} />
</div>
</div>

Related

Is there a way to handle state in a form that is dynamically built based off of parameters sent from the back end

I have a page in react 18 talking to a server which is passing information about how to build specific elements in a dynamic form. I am trying to figure out how to manage state in a case where there are multiple selects/multiselects in the page. Using one hook will not work separately for each dropdown field.
Code is updated with the latest updates. Only having issues with setting default values at this point. Hooks will not initially set values when given.
import { Calendar } from 'primereact/calendar';
import { Dropdown } from 'primereact/dropdown';
import { InputSwitch } from 'primereact/inputswitch';
import { InputText } from 'primereact/inputtext';
import { MultiSelect } from 'primereact/multiselect';
import React, { useEffect, useState, VFC } from 'react';
import { useLocation } from 'react-router-dom';
import { useEffectOnce } from 'usehooks-ts';
import { useAppDispatch, useAppSelector } from 'redux/store';
import Form from '../components/ReportViewForm/Form';
import { getReportParamsAsync, selectReportParams } from '../redux/slice';
export const ReportView: VFC = () => {
const location = useLocation();
const locState = location.state as any;
const dispatch = useAppDispatch();
const reportParams = useAppSelector(selectReportParams);
const fields: JSX.Element[] = [];
const depList: any[] = [];
//const defaultValList: any[] = [];
//dynamically setting state on all dropdown and multiselect fields
const handleDdlVal = (name: string, value: string) => {
depList.forEach((dep) => {
if (name === dep.dependencies[0]) {
dispatch(getReportParamsAsync(currentMenuItem + name + value));
}
});
setState((prev: any) => {
return { ...prev, [name]: value };
});
};
//dynamically setting state on all calendar fields
const handleCalVal = (name: string, value: Date) => {
setState((prev: any) => {
return { ...prev, [name]: value };
});
};
//dynamically setting state on all boolean fields
const handleBoolVal = (name: string, value: boolean) => {
setState((prev: any) => {
return { ...prev, [name]: value };
});
};
/* function getInitVals(values: any) {
const defaultList: any[] = [];
values.forEach((param: any) => {
defaultList.push({ name: param.name, value: param.defaultValues[0] });
});
} */
const [state, setState] = useState<any>({});
const [currentMenuItem, setCurrentMenuItem] = useState(locState.menuItem.id.toString());
useEffectOnce(() => {}), [];
useEffect(() => {
if (reportParams?.length === 0) {
dispatch(getReportParamsAsync(currentMenuItem));
}
//reload hack in order to get page to load correct fields when navigating to another report view
if (currentMenuItem != locState.menuItem.id) {
window.location.reload();
setCurrentMenuItem(locState.menuItem.id.toString());
}
}, [dispatch, reportParams, currentMenuItem, locState, state]);
//dependency list to check for dependent dropdowns, passed to reportddl
reportParams.forEach((parameter: any) => {
if (parameter.dependencies !== null && parameter.dependencies[0] !== 'apu_id') {
depList.push(parameter);
}
});
//filter dispatched data to build correct fields with data attached.
reportParams.forEach((parameter: any, i: number) => {
if (parameter.validValuesQueryBased === true) {
if (parameter.validValues !== null && parameter.multiValue) {
const dataList: any[] = [];
parameter.validValues.map((record: { value: any; label: any }) =>
dataList.push({ id: record.value, desc: record.label }),
);
fields.push(
<span key={i} className='p-float-label col-12 mx-3 field'>
<MultiSelect
options={dataList}
name={parameter.name}
value={state[parameter.name]}
onChange={(e) => handleDdlVal(parameter.name, e.value)}
></MultiSelect>
<label className='mx-3'>{parameter.prompt.substring(0, parameter.prompt.indexOf(':'))}</label>
</span>,
);
} else if (parameter.validValues !== null) {
const dataList: any[] = [];
parameter.validValues.map((record: { value: any; label: any }) =>
dataList.push({ id: record.value, desc: record.label }),
);
fields.push(
<span key={i} className='p-float-label col-12 mx-3 field'>
<Dropdown
options={dataList}
optionValue='id'
optionLabel='desc'
name={parameter.name}
onChange={(e) => handleDdlVal(parameter.name, e.value)}
value={state[parameter.name]}
//required={parameter.parameterStateName}
placeholder={'Select a Value'}
></Dropdown>
<label className='mx-3'>{parameter.prompt.substring(0, parameter.prompt.indexOf(':'))}</label>
</span>,
);
}
} else if (parameter.parameterTypeName === 'Boolean') {
fields.push(
<span key={i} className='col-12 mx-3 field-checkbox'>
<InputSwitch
checked={state[parameter.name]}
id={parameter.id}
name={parameter.name}
onChange={(e) => handleBoolVal(parameter.name, e.value)}
></InputSwitch>
<label className='mx-3'>{parameter.prompt.substring(0, parameter.prompt.indexOf(':'))}</label>
</span>,
);
} else if (parameter.parameterTypeName === 'DateTime') {
//const date = new Date(parameter.defaultValues[0]);
fields.push(
<span key={i} className='p-float-label col-12 mx-3 field'>
<Calendar
value={state[parameter.name]}
name={parameter.name}
onChange={(e) => {
const d: Date = e.value as Date;
handleCalVal(parameter.name, d);
}}
></Calendar>
<label className='mx-3'>{parameter.prompt.substring(0, parameter.prompt.indexOf(':'))}</label>
</span>,
);
} else if (parameter.name === 'apu_id') {
return null;
} else {
fields.push(
<span key={i} className='p-float-label col-12 mx-3 field'>
<InputText name={parameter.name}></InputText>
<label className='mx-3'>{parameter.prompt.substring(0, parameter.prompt.indexOf(':'))}</label>
</span>,
);
}
});
const onSubmit = () => {
console.log(state);
};
return (
<Form onReset={null} onSubmit={onSubmit} initialValues={null} validation={null} key={null}>
{fields}
</Form>
);
};
enter code here

Taking the initial values of an object using useState hook in React

I am printing array of menu items, each has input field type number with quantity to enter for each menu item.
I'm using map function to print put all items, within is the form for each item. The only problem is when I am trying to retrieve the input value of item, the first time is taking the empty object of the useState hook that is setting the value of each item. I don't want that but only, when the value is changed. Beside that when I am clicking on arrows up and down the value of input filed is not increasing.
Can somebody help?
Here is my code of Meals.js:
import {useState, useEffect, useContext} from 'react';
import CartContext from "./store/CartContext";
const Meals = () => {
const [meals, setMeals] = useState([]);
const [meal, setMeal] = useState({});
const cartCtx = useContext(CartContext);
const fetchMeals = () => {
fetch('https://food-order-7d9f9-default-rtdb.firebaseio.com/meals.json')
.then(response => response.json() )
.then(data => {
const loadedMeals = [];
for(let key in data){
loadedMeals.push({
id: key,
meal: data[key].name,
description: data[key].description,
price: data[key].price,
quantity: 1
})
}
setMeals(loadedMeals);
})
}
useEffect(() => {
fetchMeals();
}, [])
const submitHandler = (e) => {
e.preventDefault();
cartCtx.addItem(meal)
console.log("Iz submitHandler:")
console.log(cartCtx.items)
}
const handleChange = (e, id, inputMeal, description, price) =>{
let updatedMeal = {
id: id,
meal: inputMeal,
description: description,
price: price,
quantity: +e.target.value
}
setMeal(updatedMeal)
console.log("Meal object value");
console.log(meal);
const updatedItemIndex = meals.findIndex(
i => i.id === id
)
const updatedMeals = [
...meals.slice(0, updatedItemIndex),
updatedMeal,
...meals.slice(updatedItemIndex + 1)
]
console.log("From handleChange:");
console.log(updatedMeals)
updatedMeal = {
id: "",
meal: "",
description: "",
price: "",
quantity: ""
}
}
return(
<>
{
meals.map(meal => {
return(
<div key={meal.id}>
<div>
<div>{meal.meal}</div>
<div>{meal.description}</div>
<div>{meal.price}€</div>
</div>
<div className="form-wrapper">
<form onSubmit={ e=> submitHandler(e, meal.id, meal.meal, meal.description, meal.price)}>
<input
label="Amount"
name={`${meal.id}`}
min="1"
max="5"
type="number"
value={meal.quantity}
onChange={e => handleChange(e, meal.id, meal.meal, meal.description, meal.price)}
/>
<button>+ Add</button>
</form>
</div>
</div>
)
}
)
}
</>
)
}
export default Meals;
and my demo uploaded on codesandbox.io:
https://codesandbox.io/s/wonderful-williamson-puptl?file=/src/store/CartProvider.js
Your handleChange function is wrong, On click of up and down arrow, just get the item that is being updated and update its count property.
I also updated the submitHandler.
Here is the updated Code- I hope it solves your problem .
import { useState, useEffect, useContext } from "react";
import CartContext from "./store/CartContext";
const Meals = () => {
const [meals, setMeals] = useState([]);
const cartCtx = useContext(CartContext);
const fetchMeals = () => {
fetch("https://food-order-7d9f9-default-rtdb.firebaseio.com/meals.json")
.then((response) => response.json())
.then((data) => {
const loadedMeals = [];
for (let key in data) {
loadedMeals.push({
id: key,
meal: data[key].name,
description: data[key].description,
price: data[key].price,
quantity: 1
});
}
setMeals(loadedMeals);
});
};
useEffect(() => {
fetchMeals();
}, []);
const submitHandler = (e, mealId) => {
e.preventDefault();
const updatedItemIndex = meals.findIndex((i) => i.id === mealId);
const meal = meals[updatedItemIndex];
console.log(cartCtx.items);
cartCtx.addItem({ ...meal });
};
const handleChange = (e, id, inputMeal, description, price) => {
let updatedMeal = {
id: id,
meal: inputMeal,
description: description,
price: price,
quantity: +e.target.value
};
const updatedItemIndex = meals.findIndex((i) => i.id === id);
const newMeals = [...meals];
newMeals[updatedItemIndex] = updatedMeal;
setMeals(newMeals);
};
return (
<>
{meals.map((meal) => {
return (
<div key={meal.id}>
<div>
<div>{meal.meal}</div>
<div>{meal.description}</div>
<div>{meal.price}€</div>
</div>
<div className="form-wrapper">
<form
onSubmit={(e) =>
submitHandler(
e,
meal.id,
meal.meal,
meal.description,
meal.price
)
}
>
<input
label="Amount"
name={`${meal.id}`}
min="1"
max="5"
type="number"
value={meal.quantity}
onChange={(e) =>
handleChange(
e,
meal.id,
meal.meal,
meal.description,
meal.price
)
}
/>
<button>+ Add</button>
</form>
</div>
</div>
);
})}
</>
);
};
export default Meals;

React losing checked while filtering

I cannot figure out how to add 'active' into the state of users.
For the sake of posting this here I hardcoded some users in the state, but they're supposed to be fetched from an API - and this doesn't come with 'active'. I need to be able to mark the checkboxes so that the specific user becomes active, also if active - it has to stay active when doing searches in the list through the text-input, so it doesn't reset. With what I wrote I am getting undefined for user.active. Any suggestions?
App.js
import './App.css';
import UserList from './components/UserList';
import './style/style.css';
function App() {
return (
<div className="App">
<UserList />
</div>
);
}
export default App;
UserList.js
import React, { useState, useEffect } from 'react';
function UserList() {
const [users, setUsers] = useState([
{
id: 681,
first_name: 'James',
last_name: 'Smith',
email: 'example1',
gender: 'm',
},
{
id: 3123,
first_name: 'Richard',
last_name: 'Greene',
email: 'example2',
gender: 'm',
},
{
id: 512,
first_name: 'Denise',
last_name: 'Bank',
email: 'example3',
gender: 'f',
},
{
id: 654,
first_name: 'Carl',
last_name: 'Ross',
email: 'example4',
gender: 'm',
},
]);
const [search, setSearch] = useState('');
const [filteredUsers, setFilteredUsers] = useState();
const [checkedUsers, setCheckedUsers] = useState('');
useEffect(() => {
const fetchUsers = async () => {
try {
const result = await fetch(users);
result.sort(function (a, b) {
if (a.last_name.toLowerCase() < b.last_name.toLowerCase()) return -1;
if (a.last_name.toLowerCase() > b.last_name.toLowerCase()) return 1;
else return;
});
setUsers(result);
} catch (error) {
console.log(error);
}
};
fetchUsers();
}, []);
useEffect(() => {
setFilteredUsers(
users.filter(
(user) =>
user.first_name.toLowerCase().includes(search.toLowerCase()) ||
user.last_name.toLowerCase().includes(search.toLowerCase())
)
);
}, [users, search]);
useEffect(() => {
setCheckedUsers(users.filter((user) => user.active));
}, [users]);
const changeChecked = (id) => {
users.forEach((user) => {
if (user.id === id) {
console.log(user);
if (user.active === '') {
user.active = true;
} else user.active = false;
}
});
setUsers(users);
console.log(checkedUsers);
};
return (
<div className="list-container">
<div className="search">
<input
type="text"
placeholder="Search for users"
onChange={(event) => setSearch(event.target.value)}
/>
</div>
{filteredUsers &&
filteredUsers.map((user) => (
<div
className="user-block"
key={user.id}
onClick={() => console.log(user.id, user.active)}>
<div className="details">
<h5>
{user.first_name} {user.last_name}
</h5>
<p>{user.email}</p>
</div>
<input
type="checkbox"
checked={user.active}
onClick={(event) => changeChecked(user.id)}
/>
</div>
))}
</div>
);
}
export default UserList;
A few things here:
I think you should map the user after the fetch to add the active with a default value, so it isn't undefined in any case:
useEffect(() => {
const fetchUsers = async () => {
try {
const request = await fetch(users);
const response = request.map(data => ({...data, active: true})).sort(function (a, b) {
if (a.last_name.toLowerCase() < b.last_name.toLowerCase()) return -1;
if (a.last_name.toLowerCase() > b.last_name.toLowerCase()) return 1;
else return;
});
setUsers(response);
} catch (error) {
console.log(error);
}
};
fetchUsers();
}, []);
Your filtered users is absolutely useless, you can do that with the user itself and lose the useEffect and the state variables entirely:
users.filter(user =>
user.first_name.toLowerCase().includes(search.toLowerCase()) ||
user.last_name.toLowerCase().includes(search.toLowerCase())
).map((user) => (
<div
className="user-block"
key={user.id}
onClick={() => console.log(user.id, user.active)}>
<div className="details">
<h5>
{user.first_name} {user.last_name}
</h5>
<p>{user.email}</p>
</div>
<input
type="checkbox"
checked={user.active}
onClick={(event) => changeChecked(user.id)}
/>
</div>
)
And last but not least, your changeChecked function is mutating the array. I would use .map as well instead of forEach:
const changeChecked = (id) => {
setUsers(
users.map(user => {
if (user.id === id) {
return {
...user,
active: !user.active
};
} else {
return user;
}
})
);
console.log(checkedUsers);
};

What is causing the following Firestore error in ReactJS? Function DocumentReference .update() called with invalid data. Unsupported field value:

There seems to be something wrong with the way I update state, as it gets overwritten...
import Servis from "./funkc/servisni";
import React, { useState, useEffect } from "react";
export default function ContactUpdate(props) {
const initialState = {
ime: props.item.Ime,
prezime: props.item.Prezime,
datum: props.item.Datum,
kontakt: props.item.Kontakt,
published: props.item.Published,
id: props.Id,
};
const [theItem, setTheItem] = useState();
const [message, setMessage] = useState();
useEffect(() => {
setTheItem(props.item);
console.log(theItem);
}, []);
const handleInputChange = (event) => {
const { name, value } = event.target;
setTheItem({ ...theItem, [name]: value });
console.log(theItem, props.Id);
};
the problem seems to be in the following:
const updateItem = (theItem) => {
let data = {
Ime: theItem.Ime,
Prezime: theItem.Prezime,
Kontakt: theItem.Kontakt,
Datum: theItem.Datum,
Published: true,
Id: theItem.id,
};
Servis.update(theItem.id, data)
.then(() => {
setMessage("Uspjesno ste izmijenili unos!");
})
.catch((e) => {
console.log(e);
});
};
as visible in the console.log
return (
<div className="container">
{console.log(("theItem", props.Id, theItem))}
{theItem ? (
<div className="edit-form">
<h4>Kontakt</h4>
...
<button type="submit" onClick={updateItem}>
Update
</button>
<p>{message}</p>
</div>
) : (
<div>
<br />
<p>Odaberi jedan broj...</p>
</div>
)}{" "}
</div>
);
}
The call on the updateItem function by clicking on the 'Update' button results in the error : Function DocumentReference .update() called with invalid data. Unsupported field value...
Resolved through being careful about naming variables...
</div>
<ContactUpdate item={item} id={theId} />
</div>
and then
const updateItem = () => {
let data = {
Ime: theItem.Ime,
Prezime: theItem.Prezime,
Kontakt: theItem.Kontakt,
Datum: theItem.Datum,
published: true,
id: props.id,
};
Servis.update(props.id, data)
.then(() => {
setMessage("Uspjesno ste izmijenili unos!");
})
.catch((e) => {
console.log(e);
});
};

Child components not updating global state

I am developing a form with controlled components, Material-UI and, react hooks. All of the form data is saved in a global state via a useState setter function.
Additionally, some fields need to be toggled on and off depending on the user's response which implies that its local and global state has to be reset when toggled off.
That said when two or more components are toggled off at the same time one of them fails to update the global form state.
Here is my code:
App.js
imports...
function App () {
const [formState, setFormState] = useState({
fullName: '',
email: '',
ageLevel: '',
numTitle: '',
titleTypes: '',
materialType: '',
subjInterest: ''
})
const handleTxtFldChange = (e, name) => {
setFormState({ ...formState, [name]: e.target.value })
}
return (
<>
<div className='App'>
<form noValidate autoComplete='off'>
<TextField
required
value={formState.fullName}
onChange={e => handleTxtFldChange(e, 'fullName')}
label='fullName:'
/>
<AgeLevelSelect
formState={formState}
setFormState={setFormState}
/>
<NumOfTitles
formState={formState}
setFormState={setFormState}
ageLevel={formState.ageLevel}
/>
<MaterialType
formState={formState}
setFormState={setFormState}
ageLevel={formState.ageLevel}
/>
<SubjOfInterest
formState={formState}
setFormState={setFormState}
ageLevel={formState.ageLevel}
materialType={formState.materialType}
/>
<Button
onClick={() => { submitForm() }}
>
Submit
</Button>
</form>
</div>
</>
)
}
export default App
When Adult is selected from AgeLevelSelect, numTitle and materialType will be toggled on.
The data is saved in its local and global sate.
Component: AgeLevelSelect.js
imports...
const AgeLevelSelect = ({ formState, setFormState }) => {
const [age, setAge] = useState('')
const handleChange = (event) => {
setAge(event.target.value)
setFormState({ ...formState, ageLevel: event.target.value })
}
return (
<FormControl>
<InputLabel>Age level?</InputLabel>
<Select
value={age}
onChange={handleChange}
>
<MenuItem value='School-Age'>School-Age</MenuItem>
<MenuItem value='Teens'>Teens</MenuItem>
<MenuItem value='Adults'>Adults</MenuItem>
</Select>
</FormControl>
)
}
export default AgeLevelSelect
Here we select two from the select options. The data is saved in its local and global sate.
Component: NumOfTitles.js
imports...
const NumTitles = ({ formState, setFormState, ageLevel }) => {
const [titles, setTitles] = useState('')
const [isVisible, setIsVisible] = useState('')
const handleChange = (event) => {
setTitles(event.target.value)
setFormState({ ...formState, numTitle: event.target.value })
}
useEffect(() => {
if (ageLevel === 'Adults') {
setIsVisible(true)
} else {
setValue('')
setIsVisible(false)
setFormState(prevState => {
return { ...formState, materialType: '' }
})
}
}, [ageLevel])
useEffect(() => {
if (ageLevel !== 'Adults') {
setFormState(prevState => {
return { ...formState, materialType: '' }
})
setValue('')
setIsVisible(false)
}
}, [value])
return (
isVisible &&
<FormControl>
<InputLabel id='demo-simple-select-label'>Number of titles:</InputLabel>
<Select
value={titles}
onChange={handleChange}
>
<MenuItem value='One'>One</MenuItem>
<MenuItem value='Two'>Two</MenuItem>
</Select>
</FormControl>
)
}
export default NumTitles
If you made it this far THANK YOU. We are almost done.
Here we select Non-fiction. Data gets save in local and global state.
Additionally, the subject of interest question is toggled on.
Component: MaterialType.js
imports...
const TypeOfMaterial = ({ formState, setFormState, ageLevel }) => {
const [value, setValue] = useState('')
const [isVisible, setIsVisible] = useState('')
const handleChange = (event) => {
setValue(event.target.value)
setFormState({ ...formState, materialType: event.target.value })
}
useEffect(() => {
if (ageLevel === 'Adults') {
setIsVisible(true)
} else {
setValue('')
setIsVisible(false)
setFormState(prevState => {
return { ...formState, materialType: '' }
})
}
}, [ageLevel])
useEffect(() => {
if (!isVisible) {
setFormState(prevState => {
return { ...formState, materialType: '' }
})
setValue('')
setIsVisible(false)
}
}, [isVisible])
return (
isVisible &&
<FormControl component='fieldset'>
<FormLabel component='legend'>Select type of material:</FormLabel>
<RadioGroup name='MaterialTypes' value={value} onChange={handleChange}>
<FormControlLabel
value='Mystery'
control={<Radio />}
label='Mystery'
/>
<FormControlLabel
value='NonFiction'
control={<Radio />}
label='Non-fiction'
/>
</RadioGroup>
</FormControl>
)
}
export default TypeOfMaterial
Finally, we write World War II, in the text field. The data is saved in its local and global sate.
Component: SubjOfInterest.js
imports...
import React, { useState, useEffect } from 'react'
import TextField from '#material-ui/core/TextField'
const SubjOfInterest = ({ formState, setFormState, ageLevel, materialType }) => {
const [textField, setTextField] = useState('')
const [isVisible, setIsVisible] = useState('')
const handleTxtFldChange = (e) => {
setTextField(e.target.value)
setFormState({ ...formState, subjInterest: e.target.value })
}
useEffect(() => {
if (formState.materialType === 'NonFiction') {
setIsVisible(true)
} else {
setIsVisible(false)
}
}, [materialType])
useEffect(() => {
if (formState.materialType !== 'NonFiction') {
setTextField('')
}
}, [ageLevel])
return (
isVisible &&
<TextField
value={textField}
onChange={e => handleTxtFldChange(e)}
label='Indicate subjects of interest:'
/>
)
}
export default SubjOfInterest
At this point the global state looks as follow:
{
fullName:"Jhon Doe",
ageLevel:"Adults",
numTitle:"Two",
materialType:"NonFiction",
subjInterest:"World War"
}
Then if a user changes the selected option (Adults) from the AgeLeveleSelect to a different option (teens for example) the a part of global state (numTitle, materialType, subjInterest) is expected to be cleared, instead I get this:
{
fullName:"Jhon Doe",
ageLevel:"Teens",
numTitle:"Two",
materialType:"",
subjInterest:"World War"
}
Any ideas?
I have tried many things without results.
If anyone can help will be greatly appreciated!!!
You are only clearing the materialType field:
On the NumOfTitles.js file you are setting the field "materialType" instead of the "numOfTitles" field.
On the SubjOfInterest.js you are not clearing any fields.
My suggestion is that you check the "Adults" condition on the parent component. This way you will not update the same state three times (if this occurs at the same time, this can cause some problems).
You can try doing this way:
App.js
function App () {
const [formState, setFormState] = useState({
fullName: '',
email: '',
ageLevel: '',
numTitle: '',
titleTypes: '',
materialType: '',
subjInterest: ''
})
useEffect(() => {
if(formState.ageLevel !== 'Adults') {
setFormState({
...formState,
numTitle: '',
materialType: '',
subjInterest: '',
})
}
}, [formState.ageLevel]);
// ...

Resources