如何在JavaScript异步函数中去重,渲染无重复产品类型?
去除React组件中重复producttype的渲染方案
问题描述
我在React组件中使用async函数配合axios从后端获取产品数据,但返回的数据存在重复元素,需要去除这些重复项,仅渲染producttype不重复的产品(展示url和producttype信息),请问能否实现?我的代码如下:
function Productpage(){ const [data, setData] = useState([]) let navigate = useNavigate() let getproducts = async () => { let res = await axios.get(`${env.apiurl}/users/products`) console.log(data) if (res.data.statusCode === 200) { setData(res.data.data) } else { alert(res.data.message) } } console.log(data) useEffect(() => { getproducts() }, []) return <> <div> { data.map((e,i)=>{ return <div key={i} onClick={()=>navigate(`${e.producttype}`)} > <Card style={{width:"100%", height:"250px"}}> <CardImg alt="Card image cap" src={e.url} top width="50%" height="60%" /> <CardBody> <CardTitle tag="h5"> {e.producttype} </CardTitle> </CardBody> </Card> </div> }) } </div> </> }
实现方法
当然可以实现,给你两种常用方案,按需选择:
方案1:获取数据后直接去重再存state
拿到后端返回的数据后,先对producttype做去重处理,再更新state。这种方式会直接修改组件的数据源,后续所有用到data的地方都是去重后的结果:
修改getproducts函数:
let getproducts = async () => { let res = await axios.get(`${env.apiurl}/users/products`) if (res.data.statusCode === 200) { // 去重逻辑:保留每个producttype的第一个出现项 const uniqueData = []; const seenTypes = new Set(); res.data.data.forEach(item => { if (!seenTypes.has(item.producttype)) { seenTypes.add(item.producttype); uniqueData.push(item); } }); setData(uniqueData); } else { alert(res.data.message) } }
方案2:仅在渲染时处理去重(保留原始数据)
如果需要保留完整的原始数据,只在渲染层做去重处理,就修改return里的渲染逻辑:
return <> <div> { // 先提取所有不重复的producttype,再找到对应产品渲染 Array.from(new Set(data.map(item => item.producttype))) .map(type => { // 取该类型下的第一个产品 const product = data.find(item => item.producttype === type); return <div key={type} onClick={()=>navigate(`${type}`)} > <Card style={{width:"100%", height:"250px"}}> <CardImg alt="Card image cap" src={product.url} top width="50%" height="60%" /> <CardBody> <CardTitle tag="h5"> {type} </CardTitle> </CardBody> </Card> </div> }) } </div> </>
额外提示
- 渲染时的
key建议用producttype代替原来的索引i,因为索引作为key在数据变动时可能引发组件渲染异常,而producttype是唯一值,更稳定; - 方案1适合不需要保留重复数据的场景,方案2适合后续还要用到原始完整数据的场景。
内容的提问来源于stack exchange,提问作者Saiteja
相关产品推荐
相关产品推荐

