I am a learning react and have hit a snag. I have created a custom hook to handle all my input which works fine but am having trouble clearing the form after submit. Here is my custom input hook.
export function useFormFields(initialState) {
const [fields, setValues] = useState(initialState);
return [
fields,
function(event) {
try {
const { name, value, type, checked } = event.target;
setValues({
...fields,
[name]: type === "checkbox" ? checked : value,
});
} catch (err) {
console.log(err);
}
},
];
}
This is how am calling the react hook in my component.
function NewMachine() {
let data = {
user_level:"",
name: "",
email: "",
};
let [formData, setFormData] = useFormFields(data);
const [reset, setReset] = useState(false)
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
setFormData(data);//getting error here
};
return (
<div>
<form onSubmit={handleSubmit} autoComplete="off">
<input
placeholder="Enter Name"
className="form-control"
id="name"
name="name"
onChange={setFormData}
required
/>
...>other fields
<button className="float-right btn btn-secondary" type="submit">
Create New User
</button>
</form>
</div>
);
CodePudding user response:
You're passing a object with the new values and it is expecting a React.ChangeEvent
which has a target
with the name, value, type, checked
values.
Something you can do is check if the event
is a actual React Event. If it is a actual event do your event.target
stuff else just set the values.
return [
fields,
function (event) {
if ("_reactName" in event) {
// the check
try {
const { name, value, type, checked } = event.target;
setValues({
...fields,
[name]: type === "checkbox" ? checked : value,
});
} catch (err) {
console.warn(err);
}
} else {
setValues(event);
}
},
];
Note that currently the input
has no value
prop so when resetting the values it will not update the input.
return (
<div>
<form onSubmit={handleSubmit} autoComplete="off">
<input
placeholder="Enter Name"
className="form-control"
id="name"
name="name"
value={fields["name"]} // add this here
onChange={onChange}
required
/>
<button className="float-right btn btn-secondary" type="submit">
Create New User
</button>
</form>
</div>
);
This is a way you could go but I recommend creating a reset
function which you return from the hook to handle the resetting. Since we're returning multiple values we can return them as a object {}
instead of a array, in case we don't need the reset
in some other form.
function useFormFields(initialState) {
const [fields, setValues] = useState(initialState);
const reset = (newValues = initialState) => {
setValues(newValues);
};
const onChange = (event) => {
try {
const { name, value, type, checked } = event.target;
setValues({
...fields,
[name]: type === "checkbox" ? checked : value,
});
} catch (err) {
console.error(err);
}
};
return { fields, onChange, reset };
}
Which you can use like
let { fields, onChange, reset } = useFormFields(data);
const handleSubmit = (e) => {
e.preventDefault();
console.log(fields);
reset(data);
// reset(); // or like this since the default values to reset to is the initialState
};
return (
<div>
<form onSubmit={handleSubmit} autoComplete="off">
<input
placeholder="Enter Name"
className="form-control"
id="name"
name="name"
value={fields["name"]}
onChange={onChange}
required
/>
<button className="float-right btn btn-secondary" type="submit">
Create New User
</button>
</form>
</div>
);