This is my class Content
which is rendered inside App.js
. I have read through ReactJS tutorial and understand that I need to change data without mutation.
https://reactjs.org/tutorial/tutorial.html
But even when I use slice
, the app does not re-render on state changes.
This class manage a deck of cards like below:
//omitted imports
import main_deck from ...
import side_deck from ...
export default class Content extends Component {
constructor(props) {
super(props);
this.moveToMainDeck = this.moveToMainDeck.bind(this);
this.state = {
mainDeck : main_deck,
sideDeck : side_deck
}
}
moveToMainDeck(card) {
const fromDeck = this.state.sideDeck.slice(); //copy the state data
const toDeck = this.state.mainDeck.slice();
var movable = checkMovability(fromDeck, toDeck, card);
if (movable[0] === 1) { //use slice instead of splice
var newMain = toDeck.slice(0, movable[1]).concat([card]).concat(toDeck.slice(movable[1]));
var cardIndexInSideDeck = fromDeck.indexOf(card);
var newSide = fromDeck.slice(0, cardIndexInSideDeck).concat(fromDeck.slice(cardIndexInSideDeck + 1));
this.setState({ mainDeck : newMain, sideDeck : newSide });
}
else if (movable[0] === -1)
alert("Unable to move. Main Deck is full.");
else //movable[0] === 0
alert("Unable to move. Limit reached for this card in Main Deck.");
}
render() {
return (
<div><MainDeck ... /><SideDeck ... /></div>
);
}
}
With the above code, I test the state data by printing out JSON array, the state does change after this.setState
, but the view still does not re-render.
However, I tested by replacing slice()
with push()
, everything is re-rendered after state changes, like this: fromDeck.push(card);
or toDeck.push(card);
Anyone please tell what is wrong with the slice
I am using. Thanks a lot!
You could try using, as suggested here:
const fromDeck = JSON.parse(JSON.stringify(this.state.sideDeck))
This should create a completely new copy.