I'm trying to create a reusable Toast component.
Here is the code: https://codesandbox.io/s/custom-toastify-toast-with-react-component-forked-mu2l9c?file=/src/Toast.js:146-680
When rendering the Toast component itself [Comments below], the toast will pop up beautifully.
return ( <> {/* <Toast /> */} ---> This one works perfectly. <input type="text" value={input} onChange={(e) => setInput(e.target.value)} name="input" /> </>
However, I'm trying to use the public toastMeta
to implement the call to toast. In this way, the caller only needs to enter toastMeta.message("please show up..")
to get the Toast. Optional parameters horizontal and vertical position are also passed.
Problem: Unable to use toastMeta.message("")
to call the toast component
Note: This CustomToast will be an npm package, so the caller must install this library and import toastMeta
.
export const toastMeta = { position: "top-right", message: "Error Toast" }; export const Toast = ({ className, children, ...props }) => { return ( <> <ToastContainer {...props}> {toast.error(toastMeta.message, { position: toastMeta.position, autoClose: 3000, hideProgressBar: false, closeOnClick: true, pauseOnHover: true, draggable: true, progress: undefined, theme: "colored" })} </ToastContainer> </> ); };
Calling toast after each keystroke..
const [input, setInput] = useState(""); useEffect(() => { toastMeta("Error Message.."); }, [input]); return ( <> {/* <Toast /> */} <input type="text" value={input} onChange={(e) => setInput(e.target.value)} name="input" />
Reason for creating Toast component:
is used for version control because it is one of the components of the public library. The common library contains all UI elements.
Thank you for your help. Thank you in advance.
P粉0900872282024-02-04 12:50:49
You can't call the object as a function, which is one of the reasons why the implementation is incorrect, you need to use toast's ref and then pass the value dynamically.
Please check the code, hope it helps!
App.js
import React, { useEffect, useRef, useState } from "react"; import { Toast, toastMeta } from "./Toast"; const App = () => { const [input, setInput] = useState(""); const toastRef = useRef(null); useEffect(() => { // toastMeta("Error Message.."); if (input !== "") { toastRef.current.showToast({ position: "top-right", message: "Custom Error Toast" }); } }, [input]); return ( <>setInput(e.target.value)} name="input" /> > ); }; export default App;
Toast.js
import React, { forwardRef, useImperativeHandle, useState } from "react"; import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; export const toastMeta = () => { return { position: "top-right", message: "Error Toast" }; }; export const Toast = forwardRef(({ className, children, ...props }, ref) => { const [toastConfig, setToastConfig] = useState({}); useImperativeHandle(ref, () => ({ showToast: (_data) => { setToastConfig(_data); } })); return ({toast.error(toastConfig?.message, { position: toastConfig?.position, autoClose: 3000, hideProgressBar: false, closeOnClick: true, pauseOnHover: true, draggable: true, progress: undefined, theme: "colored" })} ); });