I would like to create and edit with the same React Form.
The form is started by getting a token -- this token is used as a permission to both create and edit the form and will always be present on the landing page.
The mode (create or edit) is determined by the success of 'getting' the data associated with the token with a useEffect hook- if contribution data is fetched successfully == edit, if not == create. Thus. there is no 'id' -- here the create or edit mode is determined by a call to the backend api and the presence of a response.
I am having trouble having the data pre-populated and then responding to changes in the state.
The goal is to use the same form to create and edit the data associated with contribution. (I have simplified it to just 1 input field for simplicity)
Here is my form thus far :
import { useState, useEffect } from "react";
import axios from "axios";
const contribute = () => {
// if successful, edit mode and data used to populate form
const [contribution, setContribution] = useState({});
// values for form
const [values, setValues] = useState({
firstName: "",
lastName: "",
dob: "",
type: false,
status: true,
story: "",
});
// get token on landing
const { slug } = router.query;
// fetch contribution data
useEffect(() => {
slug && getContribution();
}, [slug]);
//fetch data and update fields
const getContribution = async () => {
try {
const {data} = await axios.get(`/api/contribution/${slug}`);
const fields = ['firstName', 'lastName', 'dob', 'type', 'status', 'story'];
fields.forEach(field => setValues({...values, field : data[field]}));
setContribution(data);
}
catch (err) {
console.log(err.response.data.error)
toast(err.response.data.error)}
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
const { data } = await axios.post(`/api/contribution/create/${slug}`, {
...values, //spread values
});
toast("Story submitted!");
router.push("/");
} catch (err) {
toast(err.response.data);
}
};
return (
<div style={{ margin: "4rem" }}>
<form className={`${atoms.form} ${forms.addContentForm}`}>
<input
className={atoms.input}
type="text"
name="first-name"
value={values.firstName}
onChange={(e) =>
setValues({ ...values, firstName: e.target.value })
}
placeholder="First name"
required
/>
<button className={atoms.button} type="submit" onClick={handleSubmit}>
{contribution ? "Edit" : "Add"}
</button>
</form>
</div>
);
};