Reputation: 544
I have a parent component that handles an error callback from its child components however in keeping with do not repeat yourself there seems to be a lot of repitition in my code id like to eliminate.
function BasicInfo() {
const {shell, ageAndGender, body} = styles;
const {dispatch, state: {firstname}} = useSignUpState();
const [firstnameError, setFirstnameError] = useState(true);
const [ageError, setAgeError] = useState(true);
const [genderError, setGenderError] = useState(true);
const [sexualOrientationError, setSexualOrientationError] = useState(true);
const [heightError, setHeightError] = useState(true);
const setUserAgeError = useCallback(val => {
setAgeError(val);
}, [setAgeError]);
const setUserGenderError = useCallback(val => {
setGenderError(val);
}, [setGenderError]);
const setUserSexualOrientationError = useCallback(val => {
setSexualOrientationError(val);
}, [setSexualOrientationError]);
const setUserHeightError = useCallback(val => {
setHeightError(val);
}, [setHeightError]);
const handleError = () => {
return firstnameError || ageError || sexualOrientationError || genderError || heightError;
}
useEffect(() => {
if (firstname === '') {
setFirstnameError(true);
} else setFirstnameError(false);
}, [firstname])
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={shell}>
<View style={{flex: 10}}>
<SignUpHeader title={`Enter a bit about\nyourself`} page={1}/>
<View style={body}>
<TextInput
autoComplete
mode="outlined"
label="Firstname"
value={firstname}
onChangeText={firstname => dispatch(setFirstname(firstname))}
style={{maxHeight: 64, marginBottom: 32}}
activeOutlineColor={"#000"}
outlineColor={"#DBDBDB"}
theme={{
colors: {
text: "#000",
placeholder: "#878787",
background: "#FFF"
}
}}
/>
<View style={ageAndGender}>
<AgeButton setBasicInfoError={setUserAgeError}/>
<GenderButton setBasicInfoError={setUserGenderError}/>
</View>
<SexualOrientationButton setBasicInfoError={setUserSexualOrientationError}/>
<HeightButton setBasicInfoError={setUserHeightError}/>
</View>
</View>
<SignUpFooter
buttonTitle="Next"
disabled={handleError()}
route="BasicInfo"
title={`Basic\nInfo`}
/>
</View>
</TouchableWithoutFeedback>
);
}
As you can see in the code above every error is passed down to its child, does something very similar to my firstname
useEffect
which checks if its not valid and sets a boolean which is then checked by the parent.
Is there a way to maybe create just one callback as say an array and say if length is > 1 set the error? Any help with this would be great to avoid duplication! Thanks
Upvotes: 0
Views: 602
Reputation: 131
This looks like something you need to condense into a single useState. If you only expect one error at a time (even if they can be fairly close together) then you can simply have
[error, useError] = useState("");
And then set the error to "age" or "gender". In UseEffect, you use a switch to handle all possible use cases.
If you want multiple errors handled at a time, it looks pretty similar, but your useState starts out looking more like this
[error, useError] = useState({
age: true, gender: true, sexualOrientation: true, height: true
})
Again, with this method, you can use a single useEffect to monitor it. To handle changing a single piece, you can use the spread operator
useError({...error, age: false})
which changes age to false, but keeps everything else the same.
Upvotes: 1