As you can see the photo:
When I input the http:localhost:3000/ or some else url. It all be redirected the wrong web:http:localhost:3000/product/productID
here are the relative codes: App.jsx. This one is setting path for the route.
import React from 'react'
import Cart from './pages/Cart'
import Home from './pages/Home'
import Login from './pages/Login'
import Product from './pages/Product'
import ProductList from './pages/ProductList'
import Register from './pages/Register'
import { BrowserRouter as Router, Navigate, Route, Routes } from "react-router-dom";
const App = () => {
const user = true;
return (
<Router>
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/products/:category" element={<ProductList />} />
<Route exact path="/product/:id" element={<Product />} />
<Route exact path="/cart" element={<Cart />} />
<Route exact path="/register" element={user ? <Navigate to="/" /> : <Register />} />
<Route exact path="/login" element={user ? <Navigate to="/" /> : <Login />} />
</Routes>
</Router>
)
}
export default App
Product.jsx This one is running product information,it's also a component.
When I run the url:http:localhost:3000/products/women,it should be show the products belongs to the category:women.
But it runs http:localhost:3000/products/productId,it's wrong.
import React from 'react'
import { useEffect, useState } from 'react';
import Product from './Product';
import axios from "axios"
const Products = ({ cate, filters, sort }) => {
//const Products = () => {
console.log(cate, filters, sort)
const [products, setProducts] = useState([]);
const [filteredProducts, setFilteredProducts] = useState([]);
useEffect(() => {
const getProducts = () => {
const res = axios.get(
cate ? `http://localhost:8000/api/products?category=${cate}`
: "http://localhost:8000/api/products")
.then(
function (res) {
setProducts(res.data);
console.log(res)
}
).catch(
function (err) {
console.log(err)
});
}
getProducts();
}, [cate]);
useEffect(() => {
cate && setFilteredProducts(
products.filter((item) => (
Object.entries(filters).every(([key, value]) => {
return item[key].includes(value);
}
)
))
)
}, [products, cate, filters])
useEffect(() => {
if ((sort === "newest")) {
setFilteredProducts((prev) =>
[...prev].sort((a, b) => a.createdAt.localeCompare(b.createdAt))
)
} else if (sort === "asc") {
setFilteredProducts((prev) =>
[...prev].sort((a, b) => a.price - b.price)
)
} else {
setFilteredProducts((prev) =>
[...prev].sort((a, b) => b.price - a.price)
)
}
},[sort])
return (
<Container >
{cate
? filteredProducts.map((item) => (
<Product item={item} key={item._id} />))
: products.slice(0, 8).map((item) => <Product item={item} key={item._id} />)}
</Container>
);
};
pages/Product.jsx. This one is running display part. http:localhost:3000/product/productID**
import { useLocation } from 'react-router-dom'
import { useState, useEffect } from 'react';
import { publicRequest } from './requestMethods';
const Product = () => {
// 回傳路徑
const location = useLocation();
const id = location.pathname.split("/")[2];
const [product, setProduct] = useState({});
useEffect(() => {
const getProduct = async () => {
try {
const res = await publicRequest.get("/product/find/" + id);
setProduct(res.data);
}
catch { }
}
getProduct();
}, [id])
ProuctList.jsx
import React from 'react'
import { mobile } from './../responsive'
import { useLocation } from 'react-router-dom';
import { useState } from 'react';
const ProductList = () => {
//回傳路徑
const location = useLocation();
const cate = location.pathname.split("/")[2];
console.log(location);
//設定selector的值,並且回傳
const [filters, setFilters] = useState({});
const [sort, setSort] = useState("newest");
const handleFilters = (e) => {
const value = e.target.value;
setFilters({
...filters,
[e.target.name]: value,
});
};
console.log(filters)
return (
<Container>
<Navbar />
<Announcement />
<Title>Dresses</Title>
<FilterContainer>
<Filter><FilterText>Filter Products:</FilterText>
<Select name="color" onChange={handleFilters}>
<Option disabled>Color</Option>
<Option>black</Option>
<Option>white</Option>
<Option>green</Option>
<Option>wheat</Option>
<Option>black</Option>
<Option>red</Option>
<Option>blue</Option>
</Select>
<Select name="size" onChange={handleFilters}>
<Option disabled>Size</Option>
<Option>XS</Option>
<Option>S</Option>
<Option>M</Option>
<Option>L</Option>
<Option>XL</Option>
</Select></Filter>
<Filter><FilterText>Sort Products:
<Select onChange={(e) => setSort(e.target.value)}>
<Option value="newest">Newest</Option>
<Option value="asc">Price(asc)</Option>
<Option value="desc">Price(desc)</Option>
</Select></FilterText></Filter>
</FilterContainer>
<Products cate={cate} filters={filters} sort={sort} />
<NewsLetter />
<Footer />
</Container>
)
}
I found that the bottom code will make the all pages redirect to the http:localhost:3000/product/productID
components/Product.jsx
const Product = ({ item }) => {
return (
<Container className='container product'>
<Circle />
<Img src={item.img} />
<Info >
<Icon >
<ShoppingCartOutlinedIcon />
</Icon>
<Icon>
<Navigate to={`/product/${item._id}`}>
<SearchOutlinedIcon />
</Navigate>
</Icon>
<Icon>
<FavoriteBorderOutlinedIcon />
</Icon>
</Info>
</Container>
)
}
The Product
component is rendering a Navigate
component to "/product/XXX"
when it is rendered. Rendering <Navigate />
will immediately effect a navigation action. It seems this Product
component is rendered as part of a list when rendering all the products. It's likely you meant to render a Link
component instead so the navigation isn't effected until the search icon is clicked.
const Product = ({ item }) => {
return (
<Container className='container product'>
<Circle />
<Img src={item.img} />
<Info >
<Icon >
<ShoppingCartOutlinedIcon />
</Icon>
<Icon>
<Link to={`/product/${item._id}`}> // <-- use Link component
<SearchOutlinedIcon />
</Link>
</Icon>
<Icon>
<FavoriteBorderOutlinedIcon />
</Icon>
</Info>
</Container>
);
};
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments