简体   繁体   中英

Why is an immutable variable getting changed by React's state machine?

I have an array const defaultButtons = [{on: false},{on: false},{on: false}] . I also have a Component called Keyboard (the keyboard has 3 buttons). I want its state.buttons to default to the defaultButtons array. So I set state.buttons to defaultButtons, but every time I change the state, it also changes the defaultButtons array. Can I in some way pass the defaultButtons array to React's state machine, without letting it change the original?


    const defaultButtons = [{on: false},{on: false},{on: false}];

    class Keyboard extends Component {
      state = {
        buttons: defaultButtons
      }

      componentDidMount(){
        this.setState({buttons: [{on: true},{on: true},{on: true}]}) // changed buttons
        console.log(defaultButtons) // [{on: true},{on: true},{on: true}] ?!?!? WTF
      }

      render(
        return(<div />)
      )

    }

The code you posted is not the code you run yourself, which makes it a bit harder to debug.

this.setState(buttons: [{on: true},{on: true},{on: true}]); // Syntax error

Because fn(buttons: [...]) is not a valid way to write javascript. I guess what you are doing in your code, is

this.setState(buttons = [{on: true},{on: true},{on: true}]);

Which I can understand, because javascript is confusing sometimes. To make the error here clearer, you could rewrite the code as

let argument = buttons = [{on: true},{on: true},{on: true}]
this.setState(argument);

Which is functionally exactly the same as the (buttons = [...]) code.

You have to use {} to indicate that what you are sending into setState is an object, like this:

this.setState({ buttons: [{on: true}, {on: true}, {on: true}] });

You're currently passing a reference to the defaultButtons variable as an initial state. If you clone the defaultButtons array you won't update the defaultButtons variable when changing the state:

  state = {
    buttons: [...defaultButtons],
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM