- 此问题在此处已有答案**:
React router 6 never unmount component when URL parameter changes(1个答案)
2小时前关门了。
我正在做一个电子商务网站。如果我点击一个产品,产品的完整描述将显示在一个新的页面称为detailPage,并会有类似的产品从API中提取的底部的detailPage。它是工作正常,直到这里。但如果我点击任何类似的产品,我希望类似的产品显示在detailPage。我怎么才能使它工作?
import React, { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import useFetch from '../../Component/UseFetch/useFetch'
import { Link } from 'react-router-dom'
import './detailPage.css'
const DetailPage = () => {
const [item, setItem] = useState([])
const [mainImg, setMainImg] = useState('')
const [sameProduct, setSameProduct] = useState([])
const { loading, products } = useFetch('https://dummyjson.com/products')
const { id } = useParams()
useEffect(()=>{
const product = products.find(product => product.id === Number(id))
if(product){
setItem(product)
setMainImg(product.thumbnail)
}
},[products])
useEffect(()=>{
const allProduct = products.filter(product => product.category === item.category)
setSameProduct(allProduct)
}, [item, products])
return (
loading ? <div style={{
width: '100vw',
height: '100vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '10vw'
}}>Loading...</div> :
<div>
<div>
<h1 className='product-headline'>Product Detail</h1>
</div>
<div className='product-box'>
<div>
{
products && item && (
<div style={{height: '320px'}}>
<img className='main-image' src={mainImg} />
</div>
)
}
<div className='short-img-box'>
{
products && item && item.images && item.images.map((image, id)=>{
return <img className='short-img' key={id} src={image} onClick={()=> setMainImg(image) }/>
})
}
</div>
</div>
<div>
{
products && item && item.price && !isNaN(item.price) && (
<div>
<h1>{item.title}</h1>
<div>
<span>Rating: {item.rating}</span>
<span>Available Stock: {item.stock}</span>
</div>
<div>
<span>{parseInt(item.price + item.price / 100 * 25)}</span><br></br>
<span>{item.price}</span>
</div>
<p>{item.description}</p>
</div>
)
}
<button>Add to cart</button>
</div>
</div>
<div>
<h1 style={{textAlign: 'center'}}>Review section</h1>
</div>
<div>
<h1 className='product-headline'>Similar Products</h1>
<div className='products'>
{
sameProduct.map((product)=>{
const {id, title, description, category, price, thumbnail, images, rating, stock} = product
return (
<div key={id} className='product'>
<Link to={`/detailpage/${id}`}><img src={thumbnail} /></Link>
<div className='product-details'>
<Link className='title' to={`/detailpage/${id}`}><h3>{title}</h3></Link>
<div className='price-rating'>
<p>${price}</p>
<p>Rating: {rating}/5</p>
</div>
</div>
<button className='add-cart'>ADD TO CART</button>
<span className='product-stock'>Stock: {stock}</span>
</div>
)
})
}
</div>
</div>
</div>
)
}
export default DetailPage
2条答案
按热度按时间plicqrtu1#
在我看来,您唯一的问题是
id
没有包含在useEffect的dependency数组中.您能确认当您点击类似产品时,url更新为新的产品ID吗?在这种情况下,您所要做的就是像这样将id包含在dependency数组中,以便在URL中的id发生更改时重新运行useEffect:
50pmv0ei2#
我认为一个很好的解决方案应该是这样的(不是在产品数组中查找产品,而是在单个请求中获取单个产品(详情页面):
当产品的
id
在URL中更改时,您将添加useEffect
钩子到句柄。所以现在当你改变这个页面上的url时,这个useEffect钩子会触发并获取当前的产品
您还可以更改
useFetch
钩子,并将useEffect
移到这个钩子上,这样,当发生更改时,它将触发请求,但从我的Angular 来看,我的第一个变体更好