Reputation: 3434
I have a table with collapsible rows, and I have two components for them, the parent is the Table
the child is each CollapsibleRow
.
The table tracks the state of items
in useEffect, and updates whenever something changes.
Each row also has its own state to track if its collapsed or not, default is collapsed (in my case false
).
Whenever the state of the Table
changes, the collapsed state, gets set back to false
(i.e. if a row was "opened" when the state change occurs, it gets closed, because its state gets set back to default closed state).
export default function Table() {
const { stock } = useContext(stockContext);
return (<Table>
{stock.map(stockItem => <TableCollapsibleRow key={uuidv4()} stockItem={stockItem}/>)}
</Table>)
}
And the basics of the row:
export default function TableCollapsibleRow({ stockItem }) {
const [stockItemOpen, setStockItemOpen] = useState(false);
const openCloseOnClickHandler = () => {
setStockItemOpen(prevState => !prevState);
}
return <Collapse onClick={openCloseOnClickHandler} in={stockItemOpen}><TableRow>.....</TableRow></Collapse>
}
So if stockItemOpen
is true
(the row is not collapsed and the additional stuff can be viewed), and stock
changes while it is true
, its set back to the default false
and it gets collapsed.
I have tried to make an arbitrary stuff
variable, to see if it the behavior is somehow related to the implementation of the table:
const [stuff, setStuff] = useState(false);
const openCloseOnClickHandler = () => {
setStuff(true);
setStockItemOpen((prevState) => !prevState);
};
console.log(`${stuff} stuff`);
It too gets set back to false, whenever state gets updated.
As far as the context of stock goes:
const [stock, setStock] = useState([]);
const addToStockOperation = (data) => {
..do some stuff with the data..
setStock(prevStock => ...code that sets new stock...)
}
And this addToStockOperation
method is used by a button within the TableCollapsibleRow
component.
Upvotes: 0
Views: 267
Reputation: 1651
You need to have a unique key
in your map
{
stock.map(stockItem => <TableCollapsibleRow key={stockItem.id} stockItem={stockItem}/>)
}
This way, React can keep tracks of children, and keep their inner states
-- UPDATE --
I see you've udapted for uuidv4
in key. So at each render, you're generating a new key
. So for React, it's a new component! You have to keep same ids at each render (that's why I was suggesting stockItem.id
)
Upvotes: 3