I am porting a JS project to React, and got stuck on form submission (using various forms in the project to update profile description, name, upload pictures etc.). The simplest/shortest one simply confirms that you wish to delete a picture that you uploaded. The API part of the project is working fine (my GET, PATCH, DELETE requests are going through), but when I press any button with type=submit, the page reloads (even though preventDefault is set).
import PopupWithForm from './PopupWithForm';
function ConfirmDeletePopup(props) {
const isLoading = props.onLoading;
function handleSubmit(e) {
e.preventDefault();
props.onSubmit(props.card)
}
return (
<PopupWithForm name={'confirm-delete-form'} title='You sure?'
isOpen={props.isOpen}
onClose={props.onClose}
onSubmit={handleSubmit}
onl oading={props.onLoading}
card={props.card}>
<fieldset className={'popup__inputs'}>
<button type="submit"
className={`popup__submit-button popup__submit-button_type_confirm-delete-form
${isLoading && '.popup__submit-button_inactive'}
popup__form-submit-button_type_confirm-delete-form`}>
{isLoading? 'Deleting...' : 'Yes'}
</button>
</fieldset>
</PopupWithForm>
)
}
export default ConfirmDeletePopup
I tried running the pressing submit with react dev tools extension open, but it didn't help. I used react dev tools extensions to double check most of the state changes (like opening the popup, and toggling the 'loading' visual state on the button etc.), which were working as intended.
And code snipets relevant to this that I have within my App.js
const [isConfirmDeletePopupOpen, setConfirmDeletePopupState] = useState(false);
const [isConfirmDeleteLoading, setConfirmDeleteLoading] = useState(false);
const [deletedCard, setDeletedCard] = useState(null);
...
function handleCardDeleteSubmit(card) {
setConfirmDeleteLoading(true);
api.deleteCard(card._id)
.then(() => {
setCards((cards) => {
return cards.filter(c => {
return c._id !== card._id
});
});
closeAllPopups();
})
.catch(err => {
console.log(err);
})
.finally(() => {
setConfirmDeleteLoading(false);
})
}
...
function handleConfirmCardDelete(card) {
setConfirmDeletePopupState(true);
setDeletedCard(card);
}
...
<ConfirmDeletePopup isOpen={isConfirmDeletePopupOpen}
onClose={closeAllPopups}
onl oading={isConfirmDeleteLoading}
card={deletedCard}
onSubmit={handleCardDeleteSubmit}/>
And PopupWithForm (in case it helps to see things more clearly).
function PopupWithForm(props) {
return (
<div className={`popup popup_type_${props.name} ${props.isOpen? 'popup_opened':''}`}>
<div className="popup__container">
<button type="button"
onClick={props.onClose}
className={`popup__close-button popup__close-button_type_${props.name}`}
aria-label={`close${props.title}`}>{}</button>
<form className={`edit-form popup__form popup__form_type_${props.name}`}
name={props.name}
id={props.name}
noValidate>
<h2 className={`popup__heading ${props.name === 'update-avatar-form'?
'popup__form-heading_type_update-avatar-form': ''}`}>{props.title}</h2>
{props.children}
</form>
</div>
</div>
)
}
export default PopupWithForm;
CodePudding user response:
Quentin was right, when I was refactoring my PopupWithForm I did not pass it the onSubmit hook, which is why the page was reloading on form submission.
The fixed version:
<form className={`edit-form popup__form popup__form_type_${props.name}`}
onSubmit={props.onSubmit}
name={props.name}
id={props.name}
noValidate>
<h2 className={`popup__heading ${props.name === 'update-avatar-form'?
'popup__form-heading_type_update-avatar-form': ''}`}>{props.title}</h2>
{props.children}
</form>
CodePudding user response:
Do you tried to wrapping your component in a tag form?
const handleSubmit = (e) => {
e.preventDefault();
}
<form submit={handleSubmit}>
<button type="submit">Send</button>
</form>
