I have an edit caption of a post feature on my app. I am fetching a get request and then save that data in a state that will display on screen. The problem here is that it take a few second to load that data on screen. After editing the caption, which I have a onChange function that will update the state with the new edited caption. The new edited caption is followed by a put request that will update the caption of the post. The problem here is that I am getting an error saying to change it to either a controlled or uncontrolled state. What is the right way of doing it?
Edit: For some reason, the error isn't showing on the console now with the same code I had previously without changes. So I guess that problem is fixed? But like I mentioned before, the caption would show up empty and then show the value of the caption 2 seconds after. Is there a way to show it instantly? Im assuming it not possible since It need to make a get request first and then store the data in the state, right?
The error I'm getting
Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
Below is my code
const PostDetail = () => {
const navigate = useNavigate();
const [inputs, setInputs] = useState({ caption: "" });
const { id } = useParams();
// once data is fetched, update the edited caption to the post
useEffect(() => {
const fetchDetails = async () => {
const res = await api.get(`/post/${id}`)
.catch((error) => console.log(error.message))
const data = await res.data;
return data;
}
fetchDetails()
.then((data) => {
setInputs({
caption: data.post.caption
});
});
}, [id]);
const sendRequest = async () => {
const res = await api.put(`/post/update/${id}`, {
caption: inputs.caption
})
.catch(error => console.log(error));
const data = await res.data;
return data;
}
const handleSubmit = (e) => {
e.preventDefault();
console.log(inputs);
sendRequest()
.then((data) => console.log(data))
.then(() => navigate('/myposts'))
}
const handleChange = (e) => {
setInputs({ caption: e.target.value })
}
return (
<div>
{inputs &&
<form onSubmit={handleSubmit}>
<Box display="flex" flexDirection="column" alignItems="center" justifyContent="center" boxShadow=" 10px 10px 20px #ccc" maxWidth={500} margin="auto" padding={3} marginTop={10} borderRadius={5}>
<Typography fontWeight={"bold"} padding={3} textAlign={"center"} fontSize={22} fontFamily="georgia">Edit Your Post</Typography>
<InputLabel sx={{ mb: 1, mt: 2, fontSize: 15 }}>Caption</InputLabel>
<TextField value={inputs.caption} name="caption" onChange={handleChange} fullWidth />
<Button variant="contained" type="submit" color="warning" sx={{ marginTop: 3 }}>Submit</Button>
</Box>
</form>
}
</div>
)
}