There is a specific route in my application which is rendering perfectly when I go there by clicking the link from homepage, but the page is just showing the JSON data when directly hitting the link or refreshing it after first render.
below is code
Homescreen
import React, {useEffect } from "react";
import {useDispatch,useSelector} from 'react-redux'
import { Row, Col } from "react-bootstrap";
import Product from "../Components/Product";
import Paginate from "../Components/Paginate"
import Loader from "../Components/loader";
import Message from '../Components/Message'
import ProductCarousel from '../Components/ProductCarousel'
import {productListAction} from '../actions/productActions'
import CategoryNavigation from '../Components/CategoryNavigation'
const HomeScreen = ({match}) => {
const keyword= match.params.keyword
const category=match.params.category
const pageNumber= match.params.pageNumber ||1
const dispatch =useDispatch()
const productList=useSelector(state=>state.productList)
const {loading,products,error, page,pages} =productList
useEffect(() => {
dispatch(productListAction(keyword,pageNumber,category))
}, [dispatch,keyword,pageNumber,category]);
return (
<>
{!keyword && pageNumber==1 && !category && <ProductCarousel/>}
{!keyword && pageNumber==1 && <CategoryNavigation/>}
<h2 className='text-center'>{category?category:'All Products'}</h2>
{loading? <Loader />:error?(
<Message variant='danger'>{error}</Message>
):
<>
<Row>
{products.map((prod) => (
<Col key={prod._id} sm={6} md={6} lg={4}>
<Product product={prod} />
</Col>
))}
</Row>
<Paginate pages={pages} page={page} keyword={keyword? keyword:''} category={category?category:''} />
</>
}
</>
);
};
export default HomeScreen;
Product
import React from "react";
import {Link} from 'react-router-dom'
import { Card } from "react-bootstrap";
import Rating from './Rating'
const Product = ({ product }) => {
return (
<Card className="my-3 p-1 rounded ">
<Link to={`/products/${product._id}`} className='mx-auto' >
<Card.Img src={product?product.image[0]:'Loading...'} variant='top' className="height-70" />
</Link>
<Card.Body >
<Link to={`/products/${product._id}`}>
<Card.Title as="div">
<div className="my-3 text-center">{product.name}</div>
</Card.Title>
</Link>
<Card.Text as ='div'>
<div className="my-3 text-center">
<Rating
rating={product.rating}
numReviews={product.numReviews}/>
</div>
</Card.Text>
<Card.Text as='div'>
<div className="my-3 text-center">
<strong> Price : Rs{" "}
{product.sellingPrice} {" "}
<span className="fullprice">
Rs{" "} {product.MRP}
</span>
</strong>
</div>
</Card.Text>
</Card.Body>
</Card>
);
};
export default Product;
ProductScreen
import React, { useState, useEffect } from "react";
import {
Row,
Col,
ListGroup,
Card,
Button,
Container,
Form,
ButtonToolbar,
} from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import { Link } from "react-router-dom";
import Rating from "../Components/Rating";
import ImageArea from "../Components/ImageArea";
import {
productDetailAction,
createProductReview,
} from "../actions/productActions";
import Loader from "../Components/loader";
import { PRODUCT_CREATE_REVIEW_RESET } from "../constants/productConstants";
import Message from "../Components/Message";
const ProductScreen = ({ match, history }) => {
const [qty, setQty] = useState(1);
const [rating, setRating] = useState(0);
const [comment, setComment] = useState("");
const [variant, setVariant] = useState([]);
const [maxQty, setMaxQty] = useState(0);
const [selectedVariant, setSelectedVariant] = useState('');
const productDetail = useSelector((state) => state.productDetail);
const { product, error, loading } = productDetail;
const userLogin = useSelector((state) => state.userLogin);
const { userInfo } = userLogin;
const productReviewCreate = useSelector((state) => state.productReviewCreate);
const {
success: successProductReview,
loading: loadingProductReview,
error: errorProductReview,
} = productReviewCreate;
const dispatch = useDispatch();
useEffect(() => {
console.log('Loading product detail page')
if (successProductReview) {
setRating(0);
setComment("");
dispatch(productDetailAction(match.params.id));
}
if (!product._id || product._id !== match.params.id) {
dispatch(productDetailAction(match.params.id));
dispatch({ type: PRODUCT_CREATE_REVIEW_RESET });
setVariant(product.countInStock);
} else {
setVariant(product.countInStock);
}
}, [dispatch, variant, product, match, successProductReview]);
const qtyChangeHandler = (event) => {
setQty(event.target.value);
};
const addToCartHandler = () => {
history.push(`/cart/${match.params.id}?qty=${qty}&&variant=${selectedVariant}`);
};
const submitHandler = (e) => {
e.preventDefault();
dispatch(
createProductReview(match.params.id, {
rating,
comment,
})
);
};
const maxQtyHandler = (max,variant)=>{
setMaxQty(max)
setSelectedVariant(variant)
}
return (
<Container>
<Link to="/">
<Button type="button" variant="dark" className="my-3">
Go Back
</Button>
</Link>
{loading ? (
<Loader />
) : error ? (
<h2>error.message</h2>
) : (
<div>
<Row>
{product != null ? (
<ImageArea image={product.image} sku={product.sku} />
) : (
<Row></Row>
)}
<Col lg={3}>
<ListGroup variant="flush">
{" "}
{/*flush - remove border other each item will be inside box */}
<ListGroup.Item>
<h4>{product.name}</h4>
</ListGroup.Item>
<ListGroup.Item>
<strong>Price : Rs</strong>{" "}
<strong> {product.sellingPrice} </strong>
<strong>
<span className="fullprice">
{product.MRP}
</span>
</strong>
</ListGroup.Item>
<ListGroup.Item>
<p>Description : {product.description}</p>
</ListGroup.Item>
<ListGroup.Item>
<Rating
rating={product.rating}
numReviews={product.numReviews}
/>
</ListGroup.Item>
</ListGroup>
</Col>
<Col lg={3}>
<Card>
<ListGroup variant="flush">
<ListGroup.Item>
<Row>
<Col>Price :</Col>
<Col>₹ {product.sellingPrice}</Col>
</Row>
</ListGroup.Item>
{/* <ListGroup.Item>
<Row>
<Col>Status :</Col>
<Col>
{product.countInStock > 0 ? "Instock" : "Out of Stock"}
</Col>
</Row>
</ListGroup.Item> */}
<ListGroup.Item>
<ButtonToolbar >
{variant && variant.length > 0
&& variant.map((v) => {
return (
<Button variant='dark' key={v.variant} disabled={v.count===0}
onClick={()=>maxQtyHandler(v.count,v.variant)} >
{v.variant}
</Button>
);
})
}
</ButtonToolbar>
</ListGroup.Item>
{maxQty > 0 && (
<ListGroup.Item>
<Row>
<Col>Quantity :</Col>
<Col>
<Form.Control
as="select"
value={qty}
onChange={qtyChangeHandler}
>
{[...Array(maxQty).keys()].map(
(x) => (
<option key={x + 1} value={x + 1}>
{x + 1}
</option>
)
)}
</Form.Control>
</Col>
</Row>
</ListGroup.Item>
)}
<ListGroup.Item>
<Button
className={
product.countInStock === 0
? "btn-block btn btn-secondary"
: "btn-block btn btn-success"
}
type="button"
disabled={maxQty === 0}
onClick={addToCartHandler}
>
Add to Cart
</Button>
</ListGroup.Item>
</ListGroup>
</Card>
</Col>
</Row>
<Row>
<Col md={6}>
<h2>Reviews</h2>
{product.reviews.length === 0 && <Message>No Reviews</Message>}
<ListGroup variant="flush">
{product.reviews.map((review) => (