react-toastify中删除数据后toast.success无法正常触发问题求助
问题分析与解决
问题根源
你的ToastContainer放在了RecipeRow组件内部,点击删除按钮执行setRecipes(recipes.filter(r => r.id !== id))后,当前这条RecipeRow会被从列表中移除并卸载,组件内的ToastContainer也会被从DOM中删掉。等后续fetch的DELETE请求成功调用toast.success时,已经没有对应的容器渲染提示,所以Toast不显示。而"Sho Toast"按钮所在的组件此时仍在DOM中,因此Toast能正常弹出。
修复方案
1. 移动ToastContainer到更高层级
把ToastContainer从RecipeRow组件里移到父组件(比如渲染所有Recipe列表的组件,或是App根组件),确保即使单个RecipeRow被卸载,ToastContainer始终存在于页面中。
示例(父组件中引入):
import { ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; // 务必引入样式文件 function RecipeList() { // ... 其他逻辑代码 return ( <> <ToastContainer autoClose={1000} /> <table> <tbody> {recipes.map(recipe => ( <RecipeRow key={recipe.id} recipe={recipe} recipes={recipes} setRecipes={setRecipes} /> ))} </tbody> </table> </> ) }
之后RecipeRow组件里无需再写<ToastContainer>,保留toast调用即可。
2. 优化状态更新时机(可选但推荐)
目前你先更新本地状态再发送删除请求,若接口请求失败,本地数据已被删除会导致数据不一致。建议等接口请求成功后再更新本地状态:
const handleDeleteRecipe = (id) => { const proceedToDelete = window.confirm("Are you sure to delete the recipe?") if (proceedToDelete) { fetch(`http://localhost:3000/recipes/${id}`, { method: "DELETE", headers: { "content-type": "application/json" }, }).then(res => { if (!res.ok) throw new Error("删除失败"); // 处理接口错误情况 return res.json(); }) .then(() => { setRecipes(prev => prev.filter(r => r.id !== id)); // 用函数式更新避免闭包问题 toast.success("Recipe deleted!"); }) .catch(err => { toast.error(err.message); // 接口失败时提示错误信息 }) } }
内容的提问来源于stack exchange,提问作者Mir Kamrul Ahsan Asif
相关产品推荐
相关产品推荐

