反应:处理状态中的对象数组

时间:2021-05-06 15:38:52

标签: reactjs state

我是 React 的新手。我做了一个简单的记忆游戏(代码如下)。

  1. 在cardClickHandler中,我在修改之前使用了lodash cloneDeep方法来克隆它。在这种情况下,有没有更好的方法来实现这一目标而无需进行全状态克隆? (请不要使用 Hook)
  2. 为什么我的 cardClickHandler 方法必须绑定到 App 对象? (没有绑定它不起作用)

感谢帮助

这是 App.js 文件

import React from 'react';
import Card from './Card';
import _ from 'lodash';
import './App.css';

const cardTypes = 4;

class App extends React.Component
{
  constructor(props) {
    super(props);
    this.state = {
      cardSet : this.initCardSet(),
      pairFound : 0,
      visibleCard : [],
      gameOver : false
    }    
    this.cardClickHandler = this.cardClickHandler.bind(this);
    this.restartHandler = this.restartHandler.bind(this);
  }

  initCardSet() {
    let cardSet = [];
    for(let i=0;i<cardTypes;i++) {
      let card1 = {
        value : i,
        visible : false,
        found : false
      }
      let card2 = {...card1};
      cardSet.push(card1,card2);      
    }
    for(let i=0;i<10000;i++) {
      let p1 = Math.floor(cardSet.length*Math.random());
      let p2 = Math.floor(cardSet.length*Math.random());
      let tmp = cardSet[p1];
      cardSet[p1] = cardSet[p2];
      cardSet[p2] = tmp;
    }

    return cardSet;
  }

  cardClickHandler(cardIndex) {
    let newState = _.cloneDeep(this.state);
    switch(newState.visibleCard.length) {
      case 0:
        newState.cardSet[cardIndex].visible = true;
        newState.visibleCard = [cardIndex];
        break;
      case 1:
          newState.cardSet[cardIndex].visible = true;
          newState.visibleCard.push(cardIndex);
          if(newState.pairFound === newState.cardSet.length/2-1) {
            newState.gameOver = true;
          }        
        break;
      case 2:
      default:
        if(newState.cardSet[newState.visibleCard[0]].value === newState.cardSet[newState.visibleCard[1]].value) {
          newState.cardSet[newState.visibleCard[0]].found = true;
          newState.cardSet[newState.visibleCard[1]].found = true;
          newState.pairFound++;
        } else {
          newState.cardSet[newState.visibleCard[0]].visible = false;
          newState.cardSet[newState.visibleCard[1]].visible = false;
        }
        newState.cardSet[cardIndex].visible = true;
        newState.visibleCard = [cardIndex];
        break;
    }
    this.setState({...newState})
  }

  restartHandler() {
    window.location.reload();
  }

  render() {
    return (<div className="container">
      <h1>Jeu du memory - React</h1>
      <p>Retrouvez les paires de cartes. Cliquer dessus pour les retourner.</p>
      <button onClick={this.restartHandler}>Recommencer</button>
      <div>
      {
        this.state.cardSet.map((card,index) => <Card 
          key={'card'+index} id={index} {...card}
          cardClickHandler={this.cardClickHandler} 
        />)
      }
      </div>
      {
        this.state.gameOver?<div className="gameOver">- Jeu Terminé -</div>:null
      }
    </div>);
  }
}

export default App;

和 Card.js 文件:

import React from 'react';

export default function Card(props)
{
    let onClickHandler = (evt) => {
        if(!props.found) {
            props.cardClickHandler(props.id)
        }
    }
 
    let css = ["card"];
    if(props.visible) {
        css.push("visible");
    }
    if(props.found) {
        css.push("found");
    }

    return <div className={css.join(" ")} onClick={onClickHandler}>
        {props.visible?props.value:''}
    </div>

}

0 个答案:

没有答案