saran
saran

Reputation: 378

How to pass props inside of Router while using React Context

I have this program where Product.js just showing a list of items with an addToCart button. In the Cart.js, I am trying to show just the items I selected. Following are the files:

App.js

import './App.css';

import React,{useState} from 'react';
import {
  Route,
  BrowserRouter as Router,
  Switch,
} from 'react-router-dom';

import Cart from './components/Cart';
import Product from './components/Product';
import {ProductProvider} from './ItemListContext';

function App() {
  const [cart, setCart]= useState([]);

  const addToCart=(product)=>{
   
    setCart([...cart, {...product}])
  
   
}
console.log(cart)
  

  return (

        <div className="App">
    <ProductProvider>
         <Router>
           <Switch>
          <Route path="/" exact
             render ={()=> < Product addToCart={addToCart}/>}
        />
       <Route path="/cart/"  exact
          render ={()=> < Cart cart = {cart}   />}
        />
</Switch>
        </Router>
    </ProductProvider>
  </div>
  );
}

export default App;

Product.js

import React,{useContext, useState} from 'react';
import {ProductContext} from '../ItemListContext';

export default function Product({addToCart}) {

    const [products, setProducts] = useContext(ProductContext) 

    return(
        <div className="main-page">
            products
        
        <h1>Product Page </h1>
        
        <div className="products" >
         {products.map((product,  idx)=>(
             <div key={idx}>
            <h3>{product.name} </h3>
           <img src= {product.image} /> cost = {product.cost} 
             <button onClick={()=>addToCart(product)}
              >Add to Cart</button>
             </div>

         ))}
         </div>
         <div>
   
         </div>
        </div>
    )
}

ItemListContext.js

import React,{createContext, useState} from 'react';

export const ProductContext = createContext();

export  function ProductProvider(props) {

    const [products, setProducts]=useState([
        {
            name: 'iPhone',
            cost : '$899.99',
            image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQB6BMWrPXA9KyTtxa6o600mjeUNJ7zSXgaNt--FDCR6YjQ4XWS5G1J3dSF5ChurfQEGxorkxYs&usqp=CAc',
          },
          {
            name: 'Samsung',
            cost : '$599.99',
            image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQUGMCcF3_XBIKH5Dja-9iCkRP4CSA-CYaylQ&usqp=CAU'
          }
    ])

    return (
        <div>
            <ProductContext.Provider value={[products, setProducts]} >
                {props.children}
            </ProductContext.Provider>
            
        </div>
    )
}

Cart.jsx

import React from 'react';

export default function Cart({cart}) {

    console.log()
    return (
        <div className="cart">
        <h1>cart {cart.length}</h1>
         <div className="products" >
          
             {cart.map((product,  idx)=>(
            <div key={idx}>
                <h3>{product.name}</h3>
                <h4>{product.cost}</h4>
                <img src={product.image} alt = {product.name} />
        </div>
      ))} 

      </div> 
      <div>

      </div>
        </div>
    )
}

I am trying to create the router link, localhost:3000/ is showing the product list, but localhost:3000/cart/ doesn't show the cart items.

However, if I remove the Routers and run the program like this: App.js

import './App.css';

import React,{useState} from 'react';
import {
  Route,
  BrowserRouter as Router,
  Switch,
} from 'react-router-dom';

import Cart from './components/Cart';
import Product from './components/Product';
import {ProductProvider} from './ItemListContext';

function App() {
  const [cart, setCart]= useState([]);

  const addToCart=(product)=>{
   
    setCart([...cart, {...product}])
  
   
}
console.log(cart)
  

  return (
  <div className="App">
     <ProductProvider>
     < Product  addToCart={addToCart}/>
     <Cart cart={cart} />
     </ProductProvider>
   </div>
  );
}

export default App;

the program works just fine. So my question is, am I doing my Routing the right way? Is this the right way to pass the cart prop?

Upvotes: 0

Views: 510

Answers (1)

tuan.tran
tuan.tran

Reputation: 1881

There are no problem with Routing, you can add the Link above that and it works as expected https://codesandbox.io/s/solitary-river-hvv2q

      ...
      <ProductProvider>
        <Router>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/cart">Cart</Link>
            </li>
          </ul>
          <Switch>
            <Route path="/" exact>
              <Product addToCart={addToCart} />
            </Route>
            <Route path="/cart/" exact>
              <Cart cart={cart} />
            </Route>
          </Switch>
        </Router>
      </ProductProvider>
      ...

When you directly navigate to /cart by typing that link on browser, your App is re-render then cart is set to empty array, you should store it in storage to prevent that issue.

Upvotes: 1

Related Questions