I created a simple example of how you can update your code, also with two components (similar to the idea by @THEtheChad), but without using context since according to react docs it is discouraged to use context directly if you want your app to be stable. If state and props management in app gets too complicated you can include redux (which internally also uses context), but for now I am not including redux since it be might over-complication in this simple case.
Here is PizzaList which has pizzas on its state. The component will render PizzaItem components and pass a callback down so that each PizzaItem can notify its parent (PizzaList) when it is clicked. PizzaList has the responsibility of toggling PizzaItem when it is clicked.
class PizzaList extends React.PureComponent {
state = {
pizzas: []
}
componentDidMount() {
// fetch data about pizzas via an API and perform this.setState
this.setState({ pizzas: [{ seat: 20, occupied: false }, { seat: 10, occupied: true }, { seat: 30, occupied: true }] });
}
handlePizzaItemClick = (pizzaInd) => {
this.setState((prevState) => {
// find clicked pizza and toggle its occupied property
const pizzas = prevState.pizzas.map((pizza, ind) => {
if (ind === pizzaInd)
return { ...pizza, ...{ occupied: !pizza.occupied } };
return pizza;
});
return { pizzas: pizzas };
});
}
render () {
return (
<ul>
{this.state.pizzas.map((pizza, index) =>
<PizzaItem
onClick={this.handlePizzaItemClick}
index={index}
pizza={pizza}
/>)}
</ul>
);
}
}
PizzaItem is a simple function component that doesn't have any state.
const PizzaItem = ({ index, pizza, onClick }) => {
const { seat, row, occupied } = pizza;
const pizzaClassName = occupied ? 'coloring' : 'colored';
return (
<li key={index}
className={pizzaClassName}
onClick={() => onClick(index)}>
Seat: {seat} {row}
</li>
);
}
Here is a working example on codesandbox.
<li/>and have it toggle itself?pizzaDatalook like?