Got a form to submit a POST CRUD operation, with data save in a MySql.
I use react-hot-toast
. Can anybody advise how to reset form's inputs on success? with simple toast i can do just .then(...)
and i'm good, but there is a delay, no loading information. So i use promise based example. And now i have no idea how to setState("")
if success, if error then do not clear. Or i could have a loading button and simple toast, but then again no idea how to sync them, or how to know data was written to update that button.
const onFormSubmit = async (e) => {
e.preventDefault()
try {
const body = {
title, //state - controlled input values
content,
}
toast.promise(
fetch('/api/post', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
}),
{
loading: 'Saving...',
success: <b>Published!</b>,
error: <b>Could not save.</b>,
}
)
// .then(() => {
// setTitle('')
// setContent('')
// })
} catch (error) {
notifyNotOk()
}
}
CodePudding user response:
I think chaining the fetch promise in the toast.promise
parameter list should work.
toast.promise(
fetch(...).then(res => {
if (res.ok) {
// success, reset form inputs
}
}),
{...}
)
CodePudding user response:
As per documentation: success
and error
do accept either Renderable, either function with 1 parameter (data or error) which should return Renderable. So here is an example:
import { useState } from "react";
import toast, { Toaster } from "react-hot-toast";
import "./styles.css";
export default function App() {
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const onFormSubmit = async (e) => {
e.preventDefault();
try {
const body = { title, content };
toast.promise(
// fetchWrapped(....
fetch("/api/post", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(body)
}),
{
loading: "Saving...",
success: (data) => {
setTitle("");
setContent("");
return <b>Published!</b>;
},
error: (err) => {
return <b>Could not save.</b>;
}
}
);
} catch (error) {
//notifyNotOk();
}
};
return (
<div className="App">
<form onSubmit={onFormSubmit}>
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<input
type="text"
value={content}
onChange={(e) => setContent(e.target.value)}
/>
<button type="submit">Submit</button>
</form>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Toaster />
</div>
);
}
Now about bad part. Looks like "react-hot-toast" is not handling promises from fetch
in a correct way. So in my case (and your original code also) for failed requests "success" will be returned. Issue on the github: