I created a custom hook, named useForm
. useForm
takes an initial object that it sets to its own state using useState
. It returns this state. The hook also takes other functions, like a getData
, and submitData
to handle data retrieval/posting. It also returns a handleOnChange
function that sets the state.
I am using this hook inside a form element, named GeneralInformationForm
. This form has a couple of inputs, data retrieval and posting functions (which are passed to the hook so that it can deal with errors).
The inputs' state is tied to the state that is returned from the useForm
hook, and the onChange method of my input is the returned handleOnChange
function from the hook.
My question is: How can I write tests to see if my form correctly submits and retrieves values, when I cannot directly set the state?
Am I supposed to fire multiple onChange
events on the inputs to set the state that way? Should I be handling my form way differently?
The reason this hook exists is to reuse logic between forms, specifically onChange and error setting logic.
I am using Jest and Enzyme.
GeneralInformationForm.tsx
:
const GeneralInformationForm = (props: IProps) => {
useEffect(() => {
if (props.partnerId) handleGetData();
}, [props.partnerId]);
const getData = async () => {
if (!props.partnerId) return initialState;
const response = await getPartner(props.partnerId);
initialState.name.value = response.data.Name;
initialState.uuid.value = response.data.UUID;
initialState.token.value = response.data.Token;
initialState.isAutoClick.value = response.data.IsAutoClickEnabled;
return initialState;
};
useEffect(() => {
if (props.isSubmitted) handleOnSubmit();
}, [props.isSubmitted]);
const submitData = async () => {
const postObject = {
Name: state.name.value,
Token: state.token.value,
IsAutoClickEnabled: state.isAutoClick.value,
};
if (props.partnerId) {
return editPartner(props.partnerId, postObject, []);
}
const response = await createPartner(postObject, []);
props.setPartnerId(response.data.UUID);
return response;
};
const {
state,
handleGetData,
handleOnChange,
handleOnSubmit,
} = useForm(initialState, submitData, props.resetSubmitted, getData);
return (
<div className={styles.formContainer}>
<TextField
name="name"
label="Partner name"
value={state.name.value}
onChange={handleOnChange}
margin="normal"
error={Boolean(state.name.error)}
helperText={state.name.error}
variant="outlined"
/>
<TextField
name="uuid"
label="Partner UUID"
disabled
value={state.uuid.value}
onChange={handleOnChange}
margin="normal"
error={Boolean(state.uuid.error)}
helperText={state.uuid.error}
variant="outlined"
/>
<TextField
name="token"
label="Token"
disabled={!props.partnerId}
value={state.token.value}
onChange={handleOnChange}
margin="normal"
error={Boolean(state.token.error)}
helperText={state.token.error}
variant="outlined"
/>
<FormControlLabel
className={styles.checkbox}
control={
<Checkbox checked={state.isAutoClick.value} onChange={handleOnChange} name="isAutoClick" />
}
label="Enable Auto-click"
/>
{!props.partnerId && (
<Button
variant="contained"
onClick={handleOnSubmit}
>
Create Partner
</Button>
)}
</div>
);
};
export default GeneralInformationForm;
const initialState = {
name: { value: '', error: '' },
uuid: { value: 'automatically generated', error: '' },
token: { value: 'automatically generated', error: '' },
isAutoClick: { value: false, error: '' },
};
useForm.tsx
:
function useForm(initialState: any, submitData: any, resetSubmitted: any, getData: any) {
const [state, setState] = useState(initialState);
const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name } = event.target;
const value = event.target.type === 'checkbox' ? event.target.checked : event.target.value;
setState((prevState: any) => ({
...prevState,
[name]: { value, error: '' },
}));
};
const handleOnSubmit = async () => {
const response = await submitData(state);
if (response === null) {
// There was no partnerId present so the form could not submit correctly
}
if (response.status === 400) {
handleErrors(response.data);
}
// if (response.status === 200) {
// handleGetData();
// }
resetSubmitted();
};
const handleGetData = async () => {
const retrievedData = await getData();
setState({ ...retrievedData });
};
const handleErrors = (errors: any) => {
// Set the errors to the state
};
return {
setState,
state,
handleOnChange,
handleOnSubmit,
handleGetData,
};
}
Aucun commentaire:
Enregistrer un commentaire