Props.history.push is not working in this case

Do you understand the reason why props.history.push(“/cart/” + props.match.params.id + “?quantity=” + quantity) is not working. It is giving me Cannot read properties of undefined (reading ‘push’)

I am aware I should receive the object history, but I cannot access to it. It says undefined.

ProductScreen

import {Link,useNavigate,useHistory, withRouter,Route} from 'react-router-dom';
import axios from 'axios';
import React,{useState,useEffect,useReducer,Component} from 'react';
import {useParams} from 'react-router-dom';
import logger from 'use-reducer-logger';
{/*import Badge from 'react-bootsrap/Button';
import Rating from '../components/Rating';
import {Helmet} from 'react-helmet-async';
import LoadingBox from '../components/LoadingBox';
import MessageBox from '../components/MessageBox';
import {getError} from '../utils';
import {Store} from '../Store'; */}


const reducer = (state,action) => {
      switch(action.type){
           case  'FETCH_REQUEST':
              return {...state,loading: true};
              case  'FETCH_SUCCESS':
               return {...state,product: action.payload,loading:false};
               case 'FETCH_FAIL':
                  return {...state,loading:false,error: action.payload};
                 default:
                  return state;
               }
   };

   
 
function ProductScreen(props){
            
     const params = useParams();
      const {_id} = params; 
      const [color, setColor] = React.useState(0);
      const [size, setSize] = React.useState(0);
      const [quantity, setQuantity] = React.useState(0);
       
      
      let varyOfColor=parseInt(color);
      let varyOfSize=parseInt(size);
      let varyOfQuantity=parseInt(quantity);
      let priceInFunctionOfColorAndSize=varyOfSize+varyOfColor;      
      
            
      const [{loading, error, product},dispatch] = useReducer(logger(reducer),{
            product: {},
            loading: true,
            error: '',
           }); 
          
      useEffect(()=>{
              const fetchData = async()=>{
               dispatch({type: 'FETCH_REQUEST'});
               try{
                  const result = await axios.get(`/api/products/${_id}`); 
                  dispatch({type: 'FETCH_SUCCESS',payload:result.data})
                  
               }catch(err){
                   dispatch({type: 'FETCH_FAIL', payload: err.message});
               }
                              
            };
              fetchData();
         },[_id]);
      
    {/* const {state,dispatch: ctxDispatch} = useContext();
      const addToCartHandler = () => {
           ctxDispatch({type: 'CART_ADD_ITEM', payload: {...product,quantity:1}})
      }*/}     
      
      const handleAddToCart = () => {
            
               
            props.history.push("/cart/" + props.match.params.id + "?quantity=" + quantity);
            
      }
            
         return(
                loading?<div>Loading...</div>
                :error? <div>{error}</div>
                :
                 <div>
                              <div>
                                    <div> 
                                          {/*<Link to="/">Back to results</Link> */}  
                                                <div className="product-report">
                                                      <Link to={`/products/${product.name}`}>
                                                            <img className="image" src={product.image} alt={product.name} ></img>      
                                                      </Link>      
                                    <div className="product-description">
                                                      <div className="name-product">{product.name}</div>
                                                      <div className="rating-product">{product.rating}</div>
                                                      
                                                      <div className="product-price-variation">
                                                                  <div className="product-price">Price:</div>
                                                                  <div className="variation-price">{"$"+(product.price+priceInFunctionOfColorAndSize)*varyOfQuantity}</div>
                                                      </div>

                                                      

                                                      <div className="product-size-variation">
                                                                  <div className="product-size">Size:</div>
                                                                  <div className="size-variation">
                                                                  
                                                                  <select className="size-select-button" value={size} onChange={(event) => {setSize(event.target.value);}}>
                                                                              {
                                                                                          product.size && Array.isArray(product.size) ? (
                                                                                          product.size.map((item, i) => (
                                                                                          <option key={i} value={i}>
                                                                                                {item}
                                                                                          </option>
                                                                                                ))
                                                                                          ) : (
                                                                                                      <option value="">No sizes available</option>
                                                                                          )
                                                                                    }
                                                                        </select>
                                                                              {/*<p>
                                                                                    <strong>Current value:</strong>
                                                                                                {size}
                                                                              </p>*/}                                                 
                                                                  </div>
                                                      </div>
                                                      <div className="product-color-variation">
                                                                  <div className="color-product">Color:</div>
                                                                  <div className="color-variation">
                                                                  <select className="color-select-button" value={color} onChange={(event) => {setColor(event.target.value);}}>
                                                                        {
                                                                        product.size && Array.isArray(product.size) ? (
                                                                              product.color.map((item, i) => (
                                                                                    <option key={i} value={i}>
                                                                                    {item}
                                                                                    </option>
                                                                                    ))
                                                                        ) : (
                                                                              <option value="">No sizes available</option>
                                                                              )
                                                                              }
                                                                        </select>
                                                                  {/* <p>
                                                                        <strong>Current value:</strong>
                                                                                                            {color}
                                                                        </p>*/}     
                                                                  </div>
                                                      </div>

                                                      
                                    </div>
                                    <div className="cart-box">
                                                      <h1 className="price-cart-box">{"$"+(product.price+priceInFunctionOfColorAndSize)*varyOfQuantity}</h1>
                                                      <h1 className="stock-cart-box">In Stock</h1>
                                                                  <div className="cart-box-buttons">
                                                                  <select className="quantity-select-button" value={quantity} onChange={(event) => {setQuantity(event.target.value);}}>
                                                                        {
                                                                        product.quantity ? (
                                                                              [...Array(product.stock).keys()].map((x) => (
                                                                                    <option key={x+1} value={x+1}>
                                                                                    {x+1}
                                                                                    </option>
                                                                                    ))
                                                                        ) : (
                                                                              <option value="">No sizes available</option>
                                                                              )
                                                                              }
                                                                        </select>
                                                                 {/* <button className="cart-button" onClick={addToCartHandler}>Add to cart</button>*/}
                                                                  <button className="cart-button" onClick={handleAddToCart}>Add to cart</button>          
                                                                  
                                                                  </div> 
                                          </div>   
                              </div>         
                              </div>

                              </div>
                </div>
         );
  }

export default ProductScreen;

App.Js

import React from 'react';
import {BrowserRouter,Route, Routes,Link} from 'react-router-dom'
import HomeScreen from './screens/HomeScreen';
import ProductScreen from './screens/ProductScreen';
import CartScreen from './screens/CartScreen';
{/* import {StoreProvider} from './Store';
import Badge from 'react-bootstrap/Badge';
import {LinkContainer} from 'react-router-bootstrap';
import {useContext} from 'react';
import {Store} from './Store';*/}

function App() {
   {/* const {state, dispatch: ctxDispatch} = useContext();
    const {cart} = state;*/}
      return (
            <BrowserRouter>
      <div>
        <nav>
        <nav>
   
{/*          <StoreProvider>*/}
                   <div className="menu-background">
                            {/*<p className="menu" >Amazonas</p>*/}
                            <Link to="/" className="menu" >amazonas</Link>

                  </div>
   
{/*               </StoreProvider>*/}
                  <div className="logo-background">
                            <p className="logo">Menu</p>
                 </div>
                
              </nav>
        </nav>
      </div>
    <Routes>
      <Route path="/product/:_id" element={<ProductScreen />}></Route>
      <Route path="/cart/:id?" element={<CartScreen />}></Route>
      <Route path="/" element={<HomeScreen />}></Route>
    
    </Routes>
</BrowserRouter>
                   )
                }

export default App;

HomeScreen

import React,{useState,useReducer,useEffect} from 'react';
import {Link } from 'react-router-dom';
import axios from 'axios';
import logger from 'use-reducer-logger';

const reducer = (state,action) => {
   switch(action.type){
        case  'FETCH_REQUEST':
           return {...state,loading: true};
           case  'FETCH_SUCCESS':
            return {...state,products: action.payload,loading:false};
            case 'FETCH_FAIL':
               return {...state,loading:false,error: action.payload};
              default:
               return state;
            }
};

function HomeScreen(){
   const [{loading, error, products},dispatch] = useReducer(logger(reducer),{
      products: [],
      loading: true,
      error: '',
     }); 
    
   useEffect(()=>{
        const fetchData = async()=>{
         dispatch({type: 'FETCH_REQUEST'});
         try{
            const result = await axios.get('/api/products'); 
            dispatch({type: 'FETCH_SUCCESS',payload:result.data})
            
         }catch(err){
             dispatch({type: 'FETCH_FAIL', payload: err.message});
         }
         const result = await axios.get('/api/products');
         
      };
        fetchData();
   },[]);
      return (
         loading?<div>Loading...</div>
         :error? <div>{error}</div>
         :
          <div>
                  <body>
                        <nav>
                              <div className="menu-background">
                                    {/*<p className="menu" >Amazonas</p>*/}
                                     <Link to="/" className="menu" >amazonas</Link>

                              </div>
                              <div className="logo-background">
                                                   <p className="logo">Menu</p>
                              </div>
                        </nav>
                        <ul className="products">
                                                {
                           products.map(product=>
                           <li>
                              <div className="product">
                                 <Link to={`/product/${product.name}`}>
                                       <img className="image" src={product.image} alt={product.name} ></img>
                                 </Link>
                                 <Link to={`/product/${product.name}`}>{product.name}</Link>
                                       <div className="rating">{product.rating}</div>
                                       <div className="price">{"$"+product.price}</div>
                                 </div>
                           </li>        
                           )
                           }
                           </ul>
               </body>
      </div>
             )          
           }
export default HomeScreen;

I looked up this code and it seems to be fine, but the undefined part means one of two things: a variable that doesn’t have a value or there is no array being pushed. In other words the value should be an array. You might post the link to the challenge or project to get more feedback.

More Info: How to Fix TypeError: Cannot read Property 'push' of Undefined in JavaScript

1 Like

This is the source of the project: https://www.youtube.com/watch?v=Fy9SdZLBTOo&t=8783s

This is the result now:

I have found out that history.props.push() is wnot valid with the currentcversion of react. You need to import useNavigate from ‘react’ and use navigate(). But, I am facing this new error now.

import React from 'react';
import {BrowserRouter,Route, Routes,Link} from 'react-router-dom'
import HomeScreen from './screens/HomeScreen';
import ProductScreen from './screens/ProductScreen';
import CartScreen from './screens/CartScreen';
{/* import {StoreProvider} from './Store';
import Badge from 'react-bootstrap/Badge';
import {LinkContainer} from 'react-router-bootstrap';
import {useContext} from 'react';
import {Store} from './Store';*/}

function App() {
  {/* const {state, dispatch: ctxDispatch} = useContext();
   const {cart} = state;*/}
     return (
           <BrowserRouter>
     <div>
       <nav>
       <nav>
  
{/*          <StoreProvider>*/}
                  <div className="menu-background">
                           {/*<p className="menu" >Amazonas</p>*/}
                           <Link to="/" className="menu" >amazonas</Link>

                 </div>
  
{/*               </StoreProvider>*/}
                 <div className="logo-background">
                           <p className="logo">Menu</p>
                </div>
               
             </nav>
       </nav>
     </div>
   <Routes>
     <Route path="/product/:_id" element={<ProductScreen />}></Route>
     <Route path="/cart/:id?" element={<CartScreen />}></Route>
     <Route path="/" element={<HomeScreen />}></Route>
   
   </Routes>
</BrowserRouter>
                  )
               }

export default App;

ProductScreen.js

import {Link,useNavigate,useHistory, withRouter,Route,useParams} from 'react-router-dom';
import axios from 'axios';
import React,{useState,useEffect,useReducer,Component} from 'react';
import logger from 'use-reducer-logger';
{/*import Badge from 'react-bootsrap/Button';
import Rating from '../components/Rating';
import {Helmet} from 'react-helmet-async';
import LoadingBox from '../components/LoadingBox';
import MessageBox from '../components/MessageBox';
import {getError} from '../utils';
import {Store} from '../Store'; */}


const reducer = (state,action) => {
      switch(action.type){
           case  'FETCH_REQUEST':
              return {...state,loading: true};
              case  'FETCH_SUCCESS':
               return {...state,product: action.payload,loading:false};
               case 'FETCH_FAIL':
                  return {...state,loading:false,error: action.payload};
                 default:
                  return state;
               }
   };

   
 
function ProductScreen(props){
            
     const params = useParams();
      const {_id} = params; 
      const [color, setColor] = React.useState(0);
      const [size, setSize] = React.useState(0);
      const [quantity, setQuantity] = React.useState(1);
       const navigate = useNavigate();
      
      let varyOfColor=parseInt(color);
      let varyOfSize=parseInt(size);
      let varyOfQuantity=parseInt(quantity);
      let priceInFunctionOfColorAndSize=varyOfSize+varyOfColor;      
      
            
      const [{loading, error, product},dispatch] = useReducer(logger(reducer),{
            product: {},
            loading: true,
            error: '',
           }); 
          
      useEffect(()=>{
              const fetchData = async()=>{
               dispatch({type: 'FETCH_REQUEST'});
               try{
                  const result = await axios.get(`/api/products/${_id}`); 
                  dispatch({type: 'FETCH_SUCCESS',payload:result.data})
                  
               }catch(err){
                   dispatch({type: 'FETCH_FAIL', payload: err.message});
               }
                              
            };
              fetchData();
         },[_id]);
      
    {/* const {state,dispatch: ctxDispatch} = useContext();
      const addToCartHandler = () => {
           ctxDispatch({type: 'CART_ADD_ITEM', payload: {...product,quantity:1}})
      }*/}     
      
      const handleAddToCart = () => {
            
               
            navigate(`/cart/${_id}?quantity=${quantity}`);
            
      }
            
         return(
                loading?<div>Loading...</div>
                :error? <div>{error}</div>
                :
                 <div>
                              <div>
                                    <div> 
                                          {/*<Link to="/">Back to results</Link> */}  
                                                <div className="product-report">
                                                      <Link to={`/products/${product.name}`}>
                                                            <img className="image" src={product.image} alt={product.name} ></img>      
                                                      </Link>      
                                    <div className="product-description">
                                                      <div className="name-product">{product.name}</div>
                                                      <div className="rating-product">{product.rating}</div>
                                                      
                                                      <div className="product-price-variation">
                                                                  <div className="product-price">Price:</div>
                                                                  <div className="variation-price">{"$"+(product.price+priceInFunctionOfColorAndSize)*varyOfQuantity}</div>
                                                      </div>

                                                      

                                                      <div className="product-size-variation">
                                                                  <div className="product-size">Size:</div>
                                                                  <div className="size-variation">
                                                                  
                                                                  <select className="size-select-button" value={size} onChange={(event) => {setSize(event.target.value);}}>
                                                                              {
                                                                                          product.size && Array.isArray(product.size) ? (
                                                                                          product.size.map((item, i) => (
                                                                                          <option key={i} value={i}>
                                                                                                {item}
                                                                                          </option>
                                                                                                ))
                                                                                          ) : (
                                                                                                      <option value="">No sizes available</option>
                                                                                          )
                                                                                    }
                                                                        </select>
                                                                              {/*<p>
                                                                                    <strong>Current value:</strong>
                                                                                                {size}
                                                                              </p>*/}                                                 
                                                                  </div>
                                                      </div>
                                                      <div className="product-color-variation">
                                                                  <div className="color-product">Color:</div>
                                                                  <div className="color-variation">
                                                                  <select className="color-select-button" value={color} onChange={(event) => {setColor(event.target.value);}}>
                                                                        {
                                                                        product.size && Array.isArray(product.size) ? (
                                                                              product.color.map((item, i) => (
                                                                                    <option key={i} value={i}>
                                                                                    {item}
                                                                                    </option>
                                                                                    ))
                                                                        ) : (
                                                                              <option value="">No sizes available</option>
                                                                              )
                                                                              }
                                                                        </select>
                                                                  {/* <p>
                                                                        <strong>Current value:</strong>
                                                                                                            {color}
                                                                        </p>*/}     
                                                                  </div>
                                                      </div>

                                                      
                                    </div>
                                    <div className="cart-box">
                                                      <h1 className="price-cart-box">{"$"+(product.price+priceInFunctionOfColorAndSize)*varyOfQuantity}</h1>
                                                      <h1 className="stock-cart-box">In Stock</h1>
                                                                  <div className="cart-box-buttons">
                                                                  <select className="quantity-select-button" value={quantity} onChange={(event) => {setQuantity(event.target.value);}}>
                                                                        {
                                                                        product.quantity ? (
                                                                              [...Array(product.stock).keys()].map((x) => (
                                                                                    <option key={x+1} value={x+1}>
                                                                                    {x+1}
                                                                                    </option>
                                                                                    ))
                                                                        ) : (
                                                                              <option value="">No sizes available</option>
                                                                              )
                                                                              }
                                                                        </select>
                                                                 {/* <button className="cart-button" onClick={addToCartHandler}>Add to cart</button>*/}
                                                                  <button className="cart-button" onClick={handleAddToCart}>Add to cart</button>          
                                                                  
                                                                  </div> 
                                          </div>   
                              </div>         
                              </div>

                              </div>
                </div>
         );
  }

export default ProductScreen;

2:26h is the time he starts using the function.

Let me try to upload it in internet and I will send the link of it if God is willing.

It is solved,

I have the same answer like the video.

App.js

import React from 'react';
import {BrowserRouter,Route, Routes,Link} from 'react-router-dom'
import HomeScreen from './screens/HomeScreen';
import ProductScreen from './screens/ProductScreen';
import CartScreen from './screens/CartScreen';
{/* import {StoreProvider} from './Store';
import Badge from 'react-bootstrap/Badge';
import {LinkContainer} from 'react-router-bootstrap';
import {useContext} from 'react';
import {Store} from './Store';*/}

function App() {
   {/* const {state, dispatch: ctxDispatch} = useContext();
    const {cart} = state;*/}
      return (
            <BrowserRouter>
      <div>
        <nav>
        <nav>
   
{/*          <StoreProvider>*/}
                   <div className="menu-background">
                            {/*<p className="menu" >Amazonas</p>*/}
                            <Link to="/" className="menu" >amazonas</Link>

                  </div>
   
{/*               </StoreProvider>*/}
                  <div className="logo-background">
                            <p className="logo">Menu</p>
                 </div>
                
              </nav>
        </nav>
      </div>
    <Routes>
      <Route path="/product/:_id" element={<ProductScreen />}></Route>
{/*      <Route path="/cart/:id?" element={<CartScreen />}></Route>*/}
      <Route path="/" element={<HomeScreen />}></Route>
    
    </Routes>
</BrowserRouter>
                   )
                }

export default App;

I needed to comment this line:

<Route path="/cart/:id?" element={<CartScreen />}></Route>
1 Like