基于Redux配置react-toastify实现全局toast仅单次展示不重复
问题原因
- 你当前把
toast.error直接写在了组件渲染逻辑中,只要组件发生重渲染且错误状态符合条件,就会重复触发弹窗 - Redux中存储的错误状态未在弹窗触发后清空,路由跳转后组件重新渲染时仍能读到旧错误值,导致同个错误跨页面重复弹出
- 代码存在参数拼写不匹配问题:
afficheToast定义时接收mymessage参数,调用时传入的是message,会导致提示内容为空
修复方案
- 用
useEffect监听错误状态变化,仅在错误状态更新时触发弹窗,避免渲染时重复调用 - 弹窗触发后立刻dispatch对应的action清空Redux中的错误状态,避免后续重复读取
- 给相同错误配置固定的
toastId,天然拦截重复的同内容弹窗 - 冗余的
limit配置不需要重复写,只保留ToastContainer上的配置即可
修复后参考代码
import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import { useSelector, useDispatch } from "react-redux"; import { useEffect } from "react"; // 替换成你项目里对应清空错误的action类型即可 import { CLEAR_ERROR } from "@/store/actionTypes"; const Index = (props) => { const afficheerror = useSelector((state) => state.afficheerror); const erreur = useSelector((state) => state.erreur); const dispatch = useDispatch(); const toastProps = { position: "top-center", autoClose: 5000, hideProgressBar: false, closeOnClick: true, pauseOnHover: true, draggable: true, progress: undefined, }; useEffect(() => { // 仅当两个状态都存在时才触发弹窗 if (afficheerror && erreur) { let message = ''; let toastId = ''; switch (erreur) { case 410: message = 'My erreur 410'; toastId = 'error_410'; break; case 404: message = 'My erreur 404'; toastId = 'error_404'; break; case 422: message = 'My erreur 422'; toastId = 'error_422'; break; default: message = '未知错误'; toastId = 'error_default'; } // 相同toastId只会弹出一次 toast.error(message, { ...toastProps, toastId: toastId }); // 触发弹窗后立刻清空redux中的错误状态 dispatch({ type: CLEAR_ERROR }); } }, [afficheerror, erreur, dispatch]); return ( <> <ToastContainer limit={1} /> </> ); }; export default Index;
内容的提问来源于stack exchange,提问作者songa
相关产品推荐
相关产品推荐

