I want to pass the setState
method of the component (SnackBar
) to all the child components of the _app.js
. If I pass the setState method of SnackBar to all the child components of _app.js then it will be a very tedious task. Because, there are approx 4 levels of hierarchy from _app.js to the single component node. It includes,
_app.js -> pages -> layouts -> sections -> components
The snippet of _app.js is here.
function MyApp({ Component, pageProps }) {
const [ toastOpen, setToastOpen ] = React.useState({
msg: '',
open: false
});
React.useEffect(() => {
pageProps = { ...pageProps, setToastOpen };
}, []);
return (
<React.Fragment>
<ToastMessage
message={ toastOpen.msg }
setOpenState={ setToastOpen }
openState={ toastOpen.open }
/>
<Component {...pageProps} />
</React.Fragment>
)
}
Is there any way that I can directly import the setToastOpen
method in the child component and use it whenever I need it?
React have a special Feature called Context Api , using that you can skip the props chain passed into your components..
I recomend you to checkout below resources to learn about context Api -
Create a seperate file for Context Toast-context.js
, You can use any name you want.
import React, { useState } from "react"
const ToastContext = React.createContext({
message: "",
toastOpen: false,
toggleToast: () => { },
changeMessage: () => { }
})
export const ToastContextProvider = ({children}) => {
/*you need to use
this component to wrap App.js so that the App.js and all of its children
and their children components and so on will get the access to the
context*/
const [toastOpen, setToastOpen] = useState(false);
const [message, setMessage] = useState("");
const toggleToast = () => {
setToastOpen(true)
}
const changeMessage = (message) => {
setMessage(message);
}
return (
<ToastContext.Provider value={
toastOpen,
message,
toggleToast,
changeMessage
}>
{children}
</ToastContext.Provider>
)
}
now in the
App.js
file you need to wrap your components with ToastContextProvider component
import React, { useContext } from "react";
import { ToastContextProvider } from "./Toast-context";
import { ToastContext } from "./Toast-context";
function MyApp({ Component, pageProps }) {
const { message, toastOpen, toggleToast, changeMessage } =
useContext(ToastContext);
return (
<ToastContextProvider>
{toastOpen && <div className="toast">{message}</div>}
</ToastContextProvider>
);
}
just import the context using useContext Hook in any component you want. you don't need to wrap with <ToastContextProvider>
in every component.
just use useContext hook and then you can see the state and as well as call the functions methods to change the state.
Also make sure to refer the above links to learn more about Context Api. Thank You