React中如何在map函数内实现独立的下拉切换功能?
嘿,我完全懂你遇到的问题!你现在用了一个单一的dropdown状态变量来控制所有行的下拉菜单,所以不管点哪一行的按钮,这个全局状态一变,所有行的下拉都会跟着展开/收起。咱们得把状态改成能单独追踪每一行的展开状态才行,给你两种实用的解决思路:
方法1:用订单ID来追踪展开状态(推荐)
因为每个订单都有唯一的_id,用它来记录当前展开的订单会比索引更可靠(毕竟如果历史记录有排序、新增的情况,索引可能会变)。
步骤如下:
- 把原来的
dropdown状态改成expandedId,初始值设为null(表示没有任何订单展开):
const [expandedId, setExpandedId] = useState(null);
- 修改点击事件处理函数,传入当前订单的
_id,切换它的展开状态:
const clickHandler = (itemId) => () => { // 如果当前订单已经是展开状态,就关闭;否则展开它 setExpandedId(prevId => prevId === itemId ? null : itemId); };
- 在下拉菜单的
className里判断,只有当前订单的_id和expandedId匹配时才显示:
<div className={expandedId === items._id ? '' : 'hidden'}> <div>{items.firstName}</div> </div>
方法2:用索引来追踪展开状态
如果你的历史记录不会有排序、增删的情况,用索引也可以:
- 修改状态为
expandedIndex:
const [expandedIndex, setExpandedIndex] = useState(null);
- 点击事件传入索引:
const clickHandler = (index) => () => { setExpandedIndex(prevIndex => prevIndex === index ? null : index); };
- 下拉菜单判断索引是否匹配:
<div className={expandedIndex === index ? '' : 'hidden'}> <div>{items.firstName}</div> </div>
完整修改后的代码(用ID的版本)
import React, { useEffect, useState } from 'react'; import axios from 'axios'; import { useSelector } from 'react-redux'; function OrderHistory() { const [history, setHistory] = useState([]); const [expandedId, setExpandedId] = useState(null); const auth = useSelector((state) => state.auth); const token = useSelector((state) => state.token); const { user } = auth; useEffect(() => { const getHistory = async () => { const res = await axios.get('/user/history', { headers: { Authorization: token }, userid: user._id, }); setHistory(res.data); }; getHistory(); }, [token, user._id]); const clickHandler = (itemId) => () => { setExpandedId(prevId => prevId === itemId ? null : itemId); }; return ( <div className='history-page h-screen'> <h2>History</h2> <h4>You have {history.length} ordered</h4> <table> <thead> <tr> <th>Bestellnummer</th> <th>Datum</th> <th>Summe</th> <th>Details</th> </tr> </thead> <tbody> {history.map((items) => ( <tr key={items._id}> <td>{items._id}</td> <td>{new Date(items.createdAt).toLocaleDateString()}</td> <td> {( Math.round( items.cartItems.reduce((x, item) => x + item.price, 0) * 100 ) / 100 ).toFixed(2)} € </td> <td> <button className='bg-yellow-500 hover:bg-yellow-400 text-white font-bold py-2 px-4 rounded' onClick={clickHandler(items._id)} > Show more </button> <div className={expandedId === items._id ? '' : 'hidden'}> <div>{items.firstName}</div> {/* 这里可以添加更多订单详情内容 */} </div> </td> </tr> ))} </tbody> </table> </div> ); } export default OrderHistory;
另外还要提个小细节:你原来代码里的按钮用了class,React里应该用className哦,我在修改后的代码里已经改过来了~
内容的提问来源于stack exchange,提问作者Zut4too
相关产品推荐
相关产品推荐

