I am a React beginner, trying to make a card game app (using 'react-dnd' for drag and drop functionality).
The board
state (where the cards are placed) of this app is a 4x4 grid, stored as a 2d array
(Initial examples are truncated)
this.state = {
board: [
[null, null, null, null],
[null, null, null, null],
[null, null, null, null],
[null, null, null, null]
]
};
When cards are placed onto a space, this setState
function is called (using immutability-helper
):
// 'bxy' is an object containing x & y position of board to find position
// 'player' is string of either 'p1' or 'p2' to figure out which player just played the card
// 'id' is unique integer of card to provide more card information
this.setState(
{
// add new card to board
board: update(this.state.board, {
[bxy.x]: { [bxy.y]: { $set: { id, player, x, y } } }
})
},
// callback to run game logic based on newly placed card
this.runAfterSetState(player, bxy, id)
);
// Board would look something like this after first card placed:
// board: [
// [null, null, null, null],
// [null, {id: 3, player: "p1", x: 1, y: 1}, null, null],
// [null, null, null, null],
// [null, null, null, null]
// ]
That setState
calls a callback function runAfterSetState
to run actual game logic information based on the card that was just played. Inside that function is another setState
call. This setState
would happen only under a specific instance where, if there are multiple enemy cards, a player needs to now click on one of those enemy cards. I think, in order to achieve this, I needed to add a new object key to the enemy card information in board
state (so that I can then add styles, clickHandlers, etc). I think this is where things are going wrong.
if (enemyCards > 1) {
// new object key to add
let objToAdd = { waitingToBeSelected: true };
// update card object in board state with new object above
enemyCards.map(card => {
this.setState({
board: update(this.state.board, {
[card.x]: { [card.y]: { $merge: objToAdd } }
})
});
});
// this shows the correctly updated information
console.log(this.state.board);
}
While that console log above seems to show that the information is correctly updated, the program does not actually reflect this (using the React inspector Chrome tool). I suspect my program is re-rendering the Board
component again without this newly updated information, essentially erasing it? As far as I can tell, this code block above should be the last thing that is called, and thusly should be what the component state is at the end.
Any help here would be greatly appreciated.
Codesandbox with full working code (and my dumb comments):
https://codesandbox.io/s/billowing-leaf-81hw9?fontsize=14
To see my specific issue, one colored card must have 2 or more arrows touching adjacent enemy cards arrows. Example image: https://i.stack.imgur.com/hlJUA.png (Red Card's Top Left and Left arrows are touching enemy Blue Cards arrows)