为什么我不能使用setState将对象传递给state?

时间:2018-03-02 16:51:02

标签: javascript reactjs

我在最近2个小时内一直在盯着同一段代码,并且无法理解为什么onReveal()方法中的setState没有更新构造函数的状态。我已经检查过,我似乎正在创建一个有效的对象(r​​evealArray),但这似乎并没有被传递到州,无论我做什么。

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './App.css';

const Card = (props) => {
  return <div 
    key={props.id} 
    className="Card" 
    style={props.cardState===CardState.hidden ? {backgroundColor: "dimGrey"} : {backgroundColor: props.colour}}
    onClick={() => {props.onReveal(props.id)}}
  >
    Hello from {props.colour} Card number {props.id}. cardState is {props.cardState}
  </div>;
}

Card.propTypes = {
  onReveal: PropTypes.func.isRequired,
};

class CardHolder extends Component {
    static propTypes = {
      cards: PropTypes.arrayOf(PropTypes.object).isRequired,
    }
    render() {
        const {onReveal} = this.props;
        const AllCards = this.props.cards.map((r, index) => (
          <Card key={r.id} {...r} onReveal={onReveal}/>
        ));
        return (
            <div className="Board">
              {AllCards}
            </div>
        );

    }
}

const CardState = {
  hidden: 0,
  visible: 1,
  paired: 2
}

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      cards:  [
                {id: 0, cardState: CardState.hidden, colour: "red"},
                {id: 1, cardState: CardState.hidden, colour: "red"},
                {id: 2, cardState: CardState.hidden, colour: "blue"},
                {id: 3, cardState: CardState.hidden, colour: "blue"},
              ]
    };
    this.onReveal = this.onReveal.bind(this);
  }

  onReveal(id) {
    const revealedArray = this.state.cards.map((val, ind) => 
      (val.id === id ? 
        (val = {id: id, cardState: CardState.visible, colour: val.colour}) : (val = val)
      )
    );
    this.setState({revealedArray}, function() {
      console.log(this.state.cards);
    });
  }


  render() {
    return (
      <div className="App">
        <div className="header">
          <h1>
            Memory Game
          </h1>
          <a><h3>
            New Game
          </h3></a>
        </div>
        <div className="body">
          <CardHolder cards={this.state.cards} onReveal={this.onReveal}/>
        </div>
      </div>
    );
  }
}

export default App;

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

这些行:

this.setState({revealedArray}, function() {
  console.log(this.state.cards);
});

您正在设置名为revealedArrays的状态变量,其中您需要的是

this.setState({cards: revealedArray}, function() {
  console.log(this.state.cards);
});

答案 1 :(得分:0)

将对象写为{revealedArray}{revealedArray: revealedArray}的简写。因此,您要将数组分配给键revealedArray。您可以通过以下两种方式解决此问题之一:

  1. 明确地将数组分配给cards

    this.setState({cards: revealedArray}, function() {
      console.log(this.state.cards);
    });
    
  2. 将数组重命名为cards

    const cards = ...;
    this.setState({cards}, function() {
      console.log(this.state.cards);
    });