Jérémy S.
Jérémy S.

Reputation: 141

React - Default state

I have a question for you about React.

I'd like to know why my code isn't working correctly :

const DEFAULT_STATE = {
  disabledItems: [],
  wordToGuess: mots[Math.floor(Math.random() * mots.length)],
  mistakes: 0,
  lose: false,
  win: false,
}

class App extends Component {
  constructor(props) {
    super(props)
    this.state = { ...DEFAULT_STATE }
  }

  //Arrow function for binding
  //Restart the game
  resetGame = () => {
    this.setState({ ...DEFAULT_STATE })
  }

The problem is that my two states disabledItems and wordToGuess are not reset when resetGame is called...

Instead, this the code that is currently working :

const DEFAULT_STATE = {
  mistakes: 0,
  lose: false,
  win: false,
}

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      ...DEFAULT_STATE,
      disabledItems: [],
      wordToGuess: mots[Math.floor(Math.random() * mots.length)],
    }
  }

  //Arrow function for binding
  //Restart the game
  resetGame = () => {
    this.setState({
      ...DEFAULT_STATE,
      disabledItems: [],
      wordToGuess: mots[Math.floor(Math.random() * mots.length)],
    })
  }

Here, everything do just fine.

Is it a reference problem ? Please help me to understand :) ! Thanks a lot !

Upvotes: 3

Views: 14386

Answers (3)

Jérémy S.
Jérémy S.

Reputation: 141

Update :

I did something better thanks to roxxypoxxy and it works :

const DEFAULT_STATE = {
  disabledItems: [],
  mistakes: 0,
  lose: false,
  win: false,
}

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      ...DEFAULT_STATE,
      wordToGuess: mots[Math.floor(Math.random() * mots.length)],
    }
  }

  //Arrow function for binding
  //Restart the game
  resetGame = () => {
    this.setState({
      ...DEFAULT_STATE,
      wordToGuess: mots[Math.floor(Math.random() * mots.length)],
    })
  }

The problem was in my way to add something in disabledItems. I was doing this :

const disabledItems = this.state.disabledItems
disabledItems.push(letter)
this.setState({ disabledItems })

Instead of doing that :

this.setState({
  disabledItems: [...this.state.disabledItems, letter],
})

Upvotes: 0

roxxypoxxy
roxxypoxxy

Reputation: 3121

I think the issue here is the wordToGuess part. When you first declare

const DEFAULT_STATE = {
  disabledItems: [],
  wordToGuess: mots[Math.floor(Math.random() * mots.length)],
  mistakes: 0,
  lose: false,
  win: false,
}

The part mots[Math.floor(Math.random() * mots.length)] gets executed and assigns a value to wordToGuess, which the becomes constant thought the process.

When you are doing

 this.setState({
  ...DEFAULT_STATE,
  disabledItems: [],
  wordToGuess: mots[Math.floor(Math.random() * mots.length)],
})

you are recomputing wordToGuess and re-assigning it. I don't think there should be any problem with disabledItems.

So this should also work

this.setState({
  ...DEFAULT_STATE,
  wordToGuess: mots[Math.floor(Math.random() * mots.length)],
})

Upvotes: 0

Artem Mirchenko
Artem Mirchenko

Reputation: 2170

It is happened because you declare you DEFAULT_STATE object once, and all items stored in memory, and your resetGame only links to this created once object.

But you can make function which will built your state every time.

Example:

const buildState = () => ({
  disabledItems: [],
  wordToGuess: mots[Math.floor(Math.random() * mots.length)],
  mistakes: 0,
  lose: false,
  win: false,
});

class App extends Component {
  constructor(props) {
    super(props)
    this.state = { ...buildState() }
  }

  //Arrow function for binding
  //Restart the game
  resetGame = () => {
    this.setState({ ...buildState() })
  }

After that each call buildState() returns new different object.

Upvotes: 2

Related Questions