In my app, SearchParams.tsx is a form that gets the apiResponse
from the parent and uses entries in this response to set options for it’s select/dropdown menus for the user to then choose from. I have a lot of states in this component, few for setting the options available and others for tracking the options the user has selected (to submit/post on form submit). I am wondering if there is a more elegant/cleaner/concise way to do this (except combining everything in one object)? Or if having separate states tracking everything individually is a good idea in react? Is one approach better than the other? etc.
Note: I am using a third party API so don’t have any control on that front.
Here is a snippet from SearchParams.tsx:
const SearchParams = ({ apiResponse, speciesSelected }: { apiResponse: SpeciesSelectionResponse| {}, speciesSelected: string }) => {
const [desiredAge, setDesiredAge] = useState<string>("")
const [desiredGender, setDesiredGender] = useState<string>("")
const [desiredGeoRange, setDesiredGeoRange] = useState<string>("35")
const [desiredColor, setDesiredColor] = useState<string>("")
const [desiredBreed, setDesiredBreed] = useState<string>("")
const [zipCode, setZipCode] = useState<string>("")
const [species, setSpecies] = useState<string>("")
const [ageOptionsAvailable, setAgeOptionsAvailable] = useState<SubObject[]>([])
const [genderOptionsAvailable, setGenderOptionsAvailable] = useState<SubObject[]>([])
const [geoRangeOptionsAvailable, setGeoRangeOptionsAvailable] = useState<SubObject[]>([])
const [colorOptionsAvailable, setColorOptionsAvailable] = useState<SubObject[]>([])
const [breedOptionsAvailable, setBreedOptionsAvailable] = useState<SubObject[]>([])
useEffect(() => {
if (Object.keys(apiResponse).length === 0 && apiResponse.constructor === Object) {
return
}
if (Object.keys(apiResponse).length !== 0 && apiResponse.constructor === Object) {
setAgeOptionsAvailable((apiResponse as SpeciesSelectionResponse).age)
setGenderOptionsAvailable((apiResponse as SpeciesSelectionResponse).sex)
setGeoRangeOptionsAvailable((apiResponse as SpeciesSelectionResponse).geo_range)
setColorOptionsAvailable((apiResponse as SpeciesSelectionResponse).color_id)
setBreedOptionsAvailable((apiResponse as SpeciesSelectionResponse).breed_id)
setSpecies(speciesSelected)
}
}, [apiResponse])
Everything works as expected. I am just wondering if there is a more elegant/concise way of refactoring this.
2
Answers
I would say that you don’t need to wrap inputs in state.
Presumably the other state is displayed, and set by controls on this form. In that case it good to have states for each individually.
Although there is no specific pattern, I suggest that You don’t need to create a state for every entity. You can create an object state for related entities.
And to use any state for dependency you can use
To set the specific entity you can do like