I would like to for example use the React Context API to pass props to pages from the _app file.
Another use case would be to refactor a ReactJS routing, where state is passed from the app.js to pages through the route definition like so :
<Route><Component state=state/></Route>
I found this documentation but it feels like we should not touch the pageProps
as it only for staticly generated props.
Here is a concrete piece of code I am trying to fix:
const App = (Component,pageProps) => {
const [mobileOpen, setMobileOpen] = React.useState(false);
const [products, setProducts] = useState([]);
const [cart, setCart] = useState({});
const [order, setOrder] = useState({});
const [errorMessage, setErrorMessage] = useState('');
const fetchProducts = async () => {
const { data } = await commerce.products.list();
setProducts(data);
};
const fetchCart = async () => {
setCart(await commerce.cart.retrieve());
};
const handleAddToCart = async (productId, quantity) => {
const item = await commerce.cart.add(productId, quantity);
setCart(item.cart);
};
const handleUpdateCartQty = async (lineItemId, quantity) => {
const response = await commerce.cart.update(lineItemId, { quantity });
setCart(response.cart);
};
const handleRemoveFromCart = async (lineItemId) => {
const response = await commerce.cart.remove(lineItemId);
setCart(response.cart);
};
const handleEmptyCart = async () => {
const response = await commerce.cart.empty();
setCart(response.cart);
};
const refreshCart = async () => {
const newCart = await commerce.cart.refresh();
setCart(newCart);
};
const handleCaptureCheckout = async (checkoutTokenId, newOrder) => {
try {
const incomingOrder = await commerce.checkout.capture(checkoutTokenId, newOrder);
setOrder(incomingOrder);
refreshCart();
} catch (error) {
setErrorMessage(error.data.error.message);
}
};
useEffect(() => {
fetchProducts();
fetchCart();
}, []);
const handleDrawerToggle = () => setMobileOpen(!mobileOpen);
/* switch (useRouter.pathname) {
case ('/shop'):return <Products products={products} onAddToCart={handleAddToCart} handleUpdateCartQty />
case ('/cart'): return<Cart cart={cart} onUpdateCartQty={handleUpdateCartQty} onRemoveFromCart={handleRemoveFromCart} onEmptyCart={handleEmptyCart} />
case ('/checkout'): return <Checkout cart={cart} order={order} onCaptureCheckout={handleCaptureCheckout} error={errorMessage} />
}
*/
return <Component className="App" {...pageProps} />
}
export default App
Using a switch statement instead of the routing system will do:
In your example:
import {useRouter} from 'next/router'
[...]
switch (router.pathname) {
case "/shop":
return (
<div style={{ display: "flex" }}>
<CssBaseline />
<Navbar
totalItems={cart.total_items}
handleDrawerToggle={handleDrawerToggle}
/>
<Products
products={products}
onAddToCart={handleAddToCart}
handleUpdateCartQty
/>
</div>
);
case "/cart":
return (
<div style={{ display: "flex" }}>
<CssBaseline />
<Navbar
totalItems={cart.total_items}
handleDrawerToggle={handleDrawerToggle}
/>
<Cart
cart={cart}
onUpdateCartQty={handleUpdateCartQty}
onRemoveFromCart={handleRemoveFromCart}
onEmptyCart={handleEmptyCart}
/>
</div>
);
case "/checkout":
return (
<div style={{ display: "flex" }}>
<CssBaseline />
<Navbar
totalItems={cart.total_items}
handleDrawerToggle={handleDrawerToggle}
/>
<Checkout
cart={cart}
order={order}
onCaptureCheckout={handleCaptureCheckout}
error={errorMessage}
/>
</div>
);
}