First of all here's the codesandbox link to the example.
What I am trying to achieve here is to have 3 states for <CellItem />
component, "active", "inactive", "semi-active".
When I click any <CellItem />
component it gets the "active" state and takes the background color. However the problem is, I also want the "adjacent" cells to get "semi-active" state and take the half transparent versions of those colors. How can I achieve this effect?
CodePudding user response:
You either keep cell "state" at the parent level in something like a Grid component and dumb down your cellItems so state should be passed in as a prop
OR
you pass in 2 functions as props to bubble up the selection event onSelect and then handle an event on another. Then you have the other cellItems decide whether or not their state should change.
CodePudding user response:
I think the React answer to this is lifting state.
How does that apply here?
To translate your goal into actions, when a cell's state changes to "active", you want it tell the cells around it that their new state is "semi-active".
Lifting state would say that your parent component App
should maintain the state of each cell. Here's an example of that component's initial state. Two cells for simplicity:
const cellData = [
{ colorName: "red", alpha: "(255,0,0,0.5)", state: "inactive" },
{ colorName: "blue", alpha: "rgba(0,0,255,0.5)", state: "active" },
]
When a cell is clicked, it calls a callback it has received as props
, i.e. handleClick(cellIndex)
. That function in the parent knows about all the cells and can update any of them accordingly.
Why is this useful?
To quote the React docs:
Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor. Let’s see how this works in action.
In this case, the parent can "see" all the cells and their states, and it knows about the position of each cell relative to the others. That puts it in the right position to decide which of all the cells are "active", "semi-active", or "inactive".