Again, React has one way data binding. If you create the view from the data, and then you change the data, the view will automatically change. I would consider a structure like this:
So, Game is the parent, and Controls and Grid are children. You are going to keep state in Game - that is where your data structure of 15X15 will be. You will decide what that data is. Maybe they are arrays of numbers and a 0 means empty and 1 means your player is there. Or it could be an object with a bunch of values - it;s up to you.
That part of the state will be passed to Grid where it will be received as props and you will conditionally render each of those squares based on the values in that data structure. Grid doesn’t know where those numbers are coming from and doesn’t care - it just know that if the data for this square is 0, the square is pink and if it is 1, the square is green (or whatever.) Part of the magic of React is that you don’t have to worry about the grid on the screen after that - if you change the data in the state of Game, then Grid will automatically update. This is one way data binding. The view is bound to the data - when the data changes, the view automatically updates. Anytime your view is dependent on something in state or something passed in as props, React does this for you.
Now, how do you change them? I would have that child component called Controls. You could do it in Game - and on the surface that would be easier - but it is bad coding practice and would be unwieldy in a large program. So, you have a component called Controls that handles all the input. So, how does the child affect the state of the parent? The parent passes a function as props that the child can call to change the state of the parent.
So Controls sees a left arrow. It calls the function given to it in props, maybe something called movePlayer(). We pass it an argument, maybe a string of value ‘left’. Back in Game, that function gets called. That function does that math - if it’s as grid (4, 5), then we need to change it to (3, 5). (For convenience, you probably have these is state in a separate variable from the grid.) You update those variables and update the grid (all using setState or course) - the grid is change - (4, 5) becomes 0 and (3, 5) becomes 1 - or however you are keeping track of where the player is.
Now, because we just changed the grid in the state of the parent, and that variable is being passed the the child Grid, Grid will automatically change to reflect the new data. This is the magic of React and one way data binding.
This process of passing data and functions back and forth is difficult at first. Here is a simple pen I wrote to show how this happens.
I suppose I might also point out something that confused me when I was learning React. State is not shared between components. Every component has its own state. Read that again. This is very important. Any data you want to share has to be passed as props (going from parent to child) or in a callback function (child to parent). In complex apps, you may have to pass it through a couple layers to get to where it is going.
But because of this “no shared state” principle, it is best to have one place where you store the state of the app, ideally the ancestor of all the components that need that state. Sometimes you have components that use their own state for things that only they need, like the input of a text box, etc.
As mentioned, these component trees can get complex and difficult to pass data around. That is why things like Flux, Redux, and Mobx exist. But for these projects, it is probably best just to get a handle on React first.
Yes. React is difficult. Yes, the material is insufficient. But you’ll get through it. I recommend seeking out some youtube code-along tutorials. Eventually it will click.
Let us know if anything needs clarification.