React中ToastContainer无法作为JSX组件使用的报错问题
解决react-toastify ToastContainer JSX组件类型报错问题
问题描述
开发React OTP组件时,使用react-toastify的ToastContainer组件出现类型报错。
错误信息
ToastContainer无法作为JSX组件使用。其返回类型'ReactElement<any, string | JSXElementConstructor> | null'不是有效的JSX元素。'ReactElement<any, string | JSXElementConstructor>'类型无法赋值给'Element'类型,key属性类型不兼容。
相关代码
import axios from "axios"; import React, { useState, useEffect } from "react"; import { ToastContainer, toast } from "react-toastify"; import loaderIcon from "../../assets/images/loader.gif"; import "react-toastify/dist/ReactToastify.css"; import { IOtpProps } from "./otp.types"; export function Otp({ showOtpForm, email, setIsLoggedIn }: IOtpProps) { const [otp, setOtp] = useState(""); const [successMsg, setSuccessMsg] = useState(""); const [otpExpired, setOtpExpired] = useState(false); const [incorrectAttempts, setIncorrectAttempts] = useState(0); const [disableResend, setDisableResend] = useState(true); const [timer, setTimer] = useState(30); const [buttonOpacity, setButtonOpacity] = useState(1); const [isLoading, setIsLoading] = useState(false); const [loginError, setLoginError] = useState(""); const [errorMessage, setErrorMessage] = useState(""); const serverUrl = "http://localhost:5000/api"; useEffect(() => { if (showOtpForm) { // Display toast message for 5 seconds toast.success("Otp has been send to your Email", { autoClose: 5000, style: { fontFamily: "Noto Sans", fontSize: "15px", fontWeight: "600", borderRadius: "14px", }, }); } }, [showOtpForm]); const handleOtpChange = (e: any) => { setOtp(e.target.value); }; const startTimer = () => { let count = 30; setDisableResend(true); const timerId = setInterval(() => { count -= 1; setTimer(count); if (count === 0) { clearInterval(timerId); setDisableResend(false); } }, 1000); }; const handleResendOtp = async (e: any) => { try { e.preventDefault(); setSuccessMsg("otp resent successfully"); setDisableResend(true); startTimer(); const res = await axios.post( `${serverUrl}/resend-otp`, { email, }, { headers: { "content-type": "application/json", }, } ); if (res.data.error === false) { setSuccessMsg("OTP resent successfully"); setDisableResend(true); setTimer(30); startTimer(); } } catch (error) { console.log(error); } }; const handleLogin = async (e: any) => { e.preventDefault(); const res = await axios.post( `${serverUrl}/verify-otp`, { email, otp, }, { headers: { "content-type": "application/json", }, } ); console.log(res.data); }; return ( <div className="otp-container"> {showOtpForm && ( <div style={{ height: "100%" }}> <ToastContainer /> <div className="otp-container"> <h2>Enter OTP</h2> <p>We have sent a 6-digit OTP in your email.</p> <div> <input type="text" className="otp-input" maxLength={6} onChange={handleOtpChange} /> </div> {(showOtpForm || otpExpired || incorrectAttempts >= 3) && ( <div className="resend-otp-btn"> <span onClick={handleResendOtp} onKeyDown={(e) => e.keyCode === 13} tabIndex={0} role="button" style={{ opacity: buttonOpacity, pointerEvents: disableResend ? "none" : "auto", }} //@ts-ignore disabled={disableResend} > Resend OTP {disableResend ? `(${timer}s)` : ""} </span> </div> )} <button className="submit-btn" onClick={handleLogin} type="button"> Submit </button> {loginError && <div style={{ color: "red" }}>{loginError}</div>} {successMsg && <div style={{ color: "green" }}>{successMsg}</div>} {errorMessage && <div style={{ color: "red" }}>{errorMessage}</div>} </div> </div> )} </div> ); }
解决方案
这个报错本质是React与react-toastify的类型定义不兼容,按以下步骤排查修复:
升级依赖版本
确保react-toastify版本与React版本匹配:React 18需要react-toastify@9.x及以上,同时更新React类型定义:npm install react-toastify@latest @types/react@latest @types/react-dom@latest移除冗余类型包
react-toastify自v8起自带类型定义,无需单独安装@types/react-toastify,如果之前装过,直接卸载:npm uninstall @types/react-toastify调整TypeScript配置
在tsconfig.json中添加或修改以下配置,跳过库类型检查以规避冲突:{ "compilerOptions": { "jsx": "react-jsx", "skipLibCheck": true } }优化组件放置
建议将ToastContainer放在组件树的顶层(比如App.tsx中),避免在条件渲染的嵌套层级中重复渲染,也能减少潜在的类型问题。
内容的提问来源于stack exchange,提问作者Abhishek Vats
相关产品推荐
相关产品推荐

