_app.js
function MyApp({ Component, pageProps }) {
return (
<Provider store={store}>
<Layout>
<Component {...pageProps} />
</Layout>
);
}
export default MyApp;
Layout.js
function Layout({ children }) {
const [cartOpen, setCartOpen] = useState(false);
const handleOpen = () => setCartOpen(!cartOpen);
return (
<>
<Cart cartOpen={cartOpen} handleOpen={handleOpen} />
<main>{children}</main>
</>
)
}
ProductPage.js
function ProductPage(props) {
return (
<div>
<button onClick={() => console.log('set state to true in cartOpen(defined in layout.js)')}
</div>
)
}
Inside the ProductPage
component which is the child component of Layout
, I want an element to have a OnClick
Event handler which will change state in Layout component to setCartOpen(true)
You can leverage React Context to make setCartOpen
available to any components down the tree.
import React, { createContext, useState } from 'react';
export const CartContext = createContext(null);
function Layout({ children }) {
const [cartOpen, setCartOpen] = useState(false);
const handleOpen = () => setCartOpen(!cartOpen);
return (
<CartContext.Provider value={{ cartOpen, setCartOpen }}>
<Cart cartOpen={cartOpen} handleOpen={handleOpen} />
<main>{children}</main>
</CartContext.Provider>
)
}
export default Layout;
Then, in your page, just retrieve setCartOpen
from context and use it.
import { CartContext } from '<your-path-to>/Layout';
function ProductPage(props) {
const { setCartOpen } = useContext(CartContext);
return (
<div>
<button onClick={() => setCartOpen(true)}>Open Cart</button>
</div>
);
}
export default ProductPage;