HOW IT WORKS - When you update a field, all of the fields after it are cleared. (It must work this way to ensure the user fills it out in order. Also a field depends on the value in the previous field) Each child component has a useEffect which should reset the field if the parent tells it to do so, then tell the parent that it has been reset by setting setClear**** back to false;
I've created a simplified example below, that resembles the structure of a more complicated form I have created in another application.
Although it works, I'm unhappy with how fields are being cleared. I feel that it should be more simple. If my form grows by adding just a single element, for example 'Name', I'd have to add state 'Name', add state for 'clearName', and add another case to my switch statement. To me, I think this is too complex considering my actual application has 8 input fields.
(The child components in the actual application are not as simple and repetitive as they are in this example... this has simplified just to focus on the clearing aspect of the code)
Any suggested improvements for my design structure would be much appreciated!
PARENT COMPONENT
import React, { useState, useEffect } from 'react';
const ParentComponent = () => {
const SPECIES_FIELD = 'speciesField';
const BREED_FIELD = 'breedField';
const COLOR_FIELD = 'colorField';
const ALL = 'all';
const [species, setSpecies] = useState('');
const [breed, setBreed] = useState('');
const [color, setColor] = useState('');
const [clearSpecies, setClearSpecies] = useState('');
const [clearBreed, setClearBreed] = useState('');
const [clearColor, setClearColor] = useState('');
const resetElementsAfter = field => {
switch (field) {
case ALL:
setClearSpecies(true);
setClearBreed(true);
setClearColor(true);
case SPECIES_FIELD:
setClearBreed(true);
setClearColor(true);
break;
case BREED_FIELD:
setClearColor(true);
break;
}
};
return (
<>
<ChooseSpecies changed={val => {resetElementsAfter(SPECIES_FIELD); setSpecies(val);}} clearField={clearSpecies} setClearField={setClearSpecies}/>
<ChooseBreed changed={val => {resetElementsAfter(BREED_FIELD); setBreed(val);}} clearField={clearBreed} setClearField={setClearBreed}/>
<ChooseColor changed={setColor} clearField={clearColor} setClearField={setClearColor}/>
<div>Species: {species}</div>
<div>Breed: {breed}</div>
<div>Color: {color}</div>
<Button onClick={() => resetElementsAfter(ALL)} />
</>
);
}
CHILD COMP - 1ST FIELD
import React, { useState, useEffect } from 'react';
const ChooseSpecies = ({ changed, clearField, setClearField }) => {
const values = ['Dog', 'Cat'];
const [fieldValue, setFieldValue] = ('');
useEffect(() => {
if(clearField){
changed('');
setFieldValue('');
setClearField(false);
}
}, [clearField]);
const handleChange = e => {
setFieldValue(e.target.value);
changed(e.target.value);
};
<Dropdown values={values} fieldValue={fieldValue} changed={handleChange}/>
}
CHILD COMP - 2ND FIELD
import React, { useState, useEffect } from 'react';
const ChooseBreed = ({ changed, clearField, setClearField }) => {
const values = [{
Dog: ['Lab', 'Staffie'],
Cat: ['Maine Coone, Sphynx']
}];
const [fieldValue, setFieldValue] = ('');
useEffect(() => {
if(clearField){
changed('');
setFieldValue('');
setClearField(false);
}
}, [clearField]);
const handleChange = e => {
setFieldValue(e.target.value);
changed(e.target.value);
};
<Dropdown values={values} fieldValue={fieldValue} changed={handleChange}/>
}
CHILD COMP - 3RD FIELD
import React, { useState, useEffect } from 'react';
const ChooseColor = ({ changed, clearField, setClearField }) => {
const values = ['Black', 'White', 'Brown'];
const [fieldValue, setFieldValue] = ('');
useEffect(() => {
if(clearField){
changed('');
setFieldValue('');
setClearField(false);
}
}, [clearField]);
const handleChange = e => {
setFieldValue(e.target.value);
changed(e.target.value);
};
<Dropdown values={values} fieldValue={fieldValue} changed={handleChange}/>
}