I’m having trouble with react useState
hook. I’m trying to clean the state on a dialog close. But theres’s always one property that does not gets updated.
Buttons:
Create btn <Button className={classes.dashboardPosts__newPost} onClick={handleClickOpen}>nuevo post</Button> Edit btn <TableCell className={classes.dashboardPosts__bodyCell}><CreateIcon onClick={(e) => { onClickEdit(e, post._id) }} /></TableCell>
—- Edit —-
Close btn <Button className={classes.dashboardPosts__modalButtons} onClick={handleClose} color="primary">Cancelar</Button>
That button opens a dialog box which has a textfield:
<Button className={classes.dashboardPosts__modalButtons} type="submit" color="primary">{input._id ? "Editar" : "Crear"}</Button>
This is how the dialog box open and closes:
const handleClickOpen = () => { setOpen(true); }; const handleClose = () => { setPreviewLink("") setFile("No se ha seleccionado ningĂșn archivo") setInput({ _id: "", p_title: "", p_body: "", p_mainImage: null, p_link: "" }) setOpen(false); };
This is the state:
const [input, setInput] = useState({ _id: "", p_title: "", p_body: "", p_mainImage: null, p_link: "" })
This is the edit button click:
const onClickEdit = (e, id) => { e.preventDefault() const p = postsList.filter((up) => { return up._id === id }) setInput({ ...input, p_body: p[0].p_body, p_title: p[0].p_title, _id: p[0]._id, p_mainImage: p[0].p_mainImage, }) setPreviewLink(p[0].p_title.replace(titleRegex, '').split(" ").join("-").toLowerCase()) setFile(p[0].p_mainImage.split("").splice(0, 40).join("") + "...") handleClickOpen(e) }
The expected functionality is that when I click the edit btn, the modal opens with the post details and when the modal is closed, clean input
so whenever I click on new post button the form is clean. However the form only gets clean when I open the modal with the new post button and then close it, not when I open it with the edit button. Everything gets cleaned but the p_title
property.
— Edit —
So the problem was in my input onChange
function, this is it:
const onInputChange = (e, name, data = "") => { e.preventDefault() setInput({ ...input, [name]: data !== "" ? data : e.target.value }) if (name === "p_title") setPreviewLink(e.target.value.replace(titleRegex, '').split(" ").join("-").toLowerCase()) if (name === "p_approved") { setInput({ ...input, [name]: !input.p_approved }) return } }
However I don’t know how to solve it. My guess is that when the editor (CKeditor) input changes, it sets p_title
to it’s original value.
Advertisement
Answer
I managed to solve it. What was happening is that whenever I updated the input
state, the ckeditor
component detected change so it changed the input
state to the one that I set before closing the dialog box.
The solution was to create a diferent function to update ckeditor
state, so the whole state doesn’t change when ckeditor
updates.
This was the new function to update ckeditor state
const onEditorChange = (e, editor) => { setCkeditor(editor.getData()) }