'React State update with button click from another component
Please read the details below of code enter image description here
This MegaMenu Component
import MenuIcon from '@mui/icons-material/Menu';
import './MegaMenu.css';
import { NavLink } from 'react-router-dom';
import ArrowRightIcon from '@mui/icons-material/ArrowRight';
const categories = [
"Sunglass",
"Footwear",
"Men Watch",
"Women Watch",
"Computer",
"SmartPhones",
"Camera",
];
const MegaMenu = () => {
return (
<div className='mega_menu_component'>
<div className='mega_menu_Items'>
<div className='mega_menus'>
<MenuIcon className='mega_menu_icon' style={{ fontSize: '40px', color: '#fff', cursor: 'pointer' }} />
<div class="menu_link_content">
<NavLink className="menu_name" to="/">Home</NavLink>
<NavLink className="menu_name" to="/products">Shop <ArrowRightIcon style={{ fontSize: 'medium' }} />
<ul className="categoryMenu">
{categories.map((categoryName) => (
<li className="categoryMenu-link" > <NavLink style={{ textDecoration: 'none', color: '#000' }} key={categoryName} to={`/products/${categoryName}`}>{categoryName}</NavLink></li>
))}
</ul>
</NavLink>
<NavLink className="menu_name" to="/contact">Contact</NavLink>
<NavLink className="menu_name" to="/about">About</NavLink>
</div>
</div>
</div>
</div>
);
};
export default MegaMenu;
**This Product Component**
import React, { Fragment, useEffect, useState } from "react";
import "./Products.css";
import { useSelector, useDispatch } from "react-redux";
import { clearErrors, getProduct } from "../../actions/productAction";
import Loader from "../layout/Loader/Loader";
import ProductCard from "../Home/ProductCard";
import Pagination from "react-js-pagination";
import Slider from "@material-ui/core/Slider";
import { useAlert } from "react-alert";
import Typography from "@material-ui/core/Typography";
import MetaData from "../layout/MetaData";
import { useParams } from "react-router";
import { NavLink, useLocation } from "react-router-dom"
const categories = [
"Sunglass",
"Footwear",
"Men Watch",
"Women Watch",
"Computer",
"SmartPhones",
"Camera",
];
const Products = ({ match }) => {
const dispatch = useDispatch();
const urlLocation = useLocation();
const categoryName = urlLocation.pathname.split('/')[2];
const alert = useAlert();
const [currentPage, setCurrentPage] = useState(1);
const [price, setPrice] = useState([0, 25000]);
// const [category, setCategory] = useState(categoryName);
const [category, setCategory] = useState('');
const [ratings, setRatings] = useState(0);
const {
products,
loading,
error,
productsCount,
resultPerPage,
filteredProductsCount,
} = useSelector((state) => state.products);
const keyword = match.params.keyword;
const setCurrentPageNo = (e) => {
setCurrentPage(e);
};
const priceHandler = (event, newPrice) => {
setPrice(newPrice);
};
let count = filteredProductsCount;
useEffect(() => {
if (error) {
alert.error(error);
dispatch(clearErrors());
}
dispatch(getProduct(keyword, currentPage, price, category, ratings));
}, [dispatch, keyword, currentPage, price, category, ratings, alert, error]);
return (
<Fragment>
{loading ? (
<Loader />
) : (
<Fragment>
<MetaData title="PRODUCTS -- ECOMMERCE" />
<h2 className="productsHeading">Products</h2>
<div className="products">
{products &&
products.map((product) => (
<ProductCard key={product._id} product={product} />
))}
</div>
<div className="filterBox">
<Typography>Price</Typography>
<Slider
value={price}
onChange={priceHandler}
valueLabelDisplay="auto"
aria-labelledby="range-slider"
min={0}
max={25000}
/>
<Typography>Categories</Typography>
<ul className="categoryBox">
{categories.map((category) => (
<li className="category-link" >
<NavLink style={{ textDecoration: 'none', color: 'black' }} key={category} onClick={() => setCategory(category)} to={`/products`}>{category}</NavLink>
</li>
))}
</ul>
<fieldset>
<Typography component="legend">Ratings Above</Typography>
<Slider
value={ratings}
onChange={(e, newRating) => {
setRatings(newRating);
}}
aria-labelledby="continuous-slider"
valueLabelDisplay="auto"
min={0}
max={5}
/>
</fieldset>
</div>
{resultPerPage < count && (
<div className="paginationBox">
<Pagination
activePage={currentPage}
itemsCountPerPage={resultPerPage}
totalItemsCount={productsCount}
onChange={setCurrentPageNo}
nextPageText="Next"
prevPageText="Prev"
firstPageText="1st"
lastPageText="Last"
itemClass="page-item"
linkClass="page-link"
activeClass="pageItemActive"
activeLinkClass="pageLinkActive"
/>
</div>
)}
</Fragment>
)}
</Fragment>
);
};
export default Products;
When I want to click on the mega menu "Shop>>Category" name the url would be like http://localhost:3000/products/Sunglass Here sunglass is category name **Now I want to data update in the Product component (ProductCard Update) using the URL category part. But it does not work. **
How can I solve this problem?
Solution 1:[1]
Well, one of possible solutions is to handle pathname change using history.listen method (https://github.com/remix-run/history/blob/dev/docs/api-reference.md#historylistenlistener-listener)
The code may look something like this:
useEffect(() => {
const unlisten = history.listen(({ action, location }) => {
// Do your magic
})
// Don't forget to unsub
return unlisten
}, [])
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Polyakov Egor |