我有一个包含可折叠行的表,我有两个组件用于它们,父项是 Table
,子项是每个 CollapsibleRow
。
该表在 useEffect 中跟踪 items
的状态,并在发生变化时更新。
每一行也有自己的状态来跟踪它是否折叠,默认是折叠的(在我的例子中是 false
)。
每当 Table
的状态发生变化时,折叠状态就会被设置回 false
(即,如果在状态发生变化时一行被“打开”,它就会被关闭,因为它的状态被设置回默认关闭状态)。
export default function Table() {
const { stock } = useContext(stockContext);
return (<Table>
{stock.map(stockItem => <TableCollapsibleRow key={uuidv4()} stockItem={stockItem}/>)}
</Table>)
}
以及行的基础知识:
export default function TableCollapsibleRow({ stockItem }) {
const [stockItemOpen, setStockItemOpen] = useState(false);
const openCloseOnClickHandler = () => {
setStockItemOpen(prevState => !prevState);
}
return <Collapse onClick={openCloseOnClickHandler} in={stockItemOpen}><TableRow>.....</TableRow></Collapse>
}
因此,如果 stockItemOpen
为 true
(该行未折叠并且可以查看其他内容),并且 stock
在 true
期间发生变化,则其回退到默认的 false
并折叠起来。
我试图创建一个任意的 stuff
变量,看看它的行为是否与表的实现有某种关系:
const [stuff, setStuff] = useState(false);
const openCloseOnClickHandler = () => {
setStuff(true);
setStockItemOpen((prevState) => !prevState);
};
console.log(`${stuff} stuff`);
每当状态更新时,它也会被设置回 false。
就股票的背景而言:
const [stock, setStock] = useState([]);
const addToStockOperation = (data) => {
..do some stuff with the data..
setStock(prevStock => ...code that sets new stock...)
}
此 addToStockOperation
方法由 TableCollapsibleRow
组件中的按钮使用。
答案 0 :(得分:3)
您的地图中需要有唯一的 key
{
stock.map(stockItem => <TableCollapsibleRow key={stockItem.id} stockItem={stockItem}/>)
}
这样,React 就可以跟踪孩子,并保持他们的内部状态
-- 更新 --
我看到你已经适应了 uuidv4
的关键。因此,在每次渲染时,您都会生成一个新的 key
。所以对于 React 来说,它是一个新组件!您必须在每次渲染时保持相同的 ID(这就是我建议 stockItem.id
)