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())
}