You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 08:44:57