对原始状态的更改副本做出反应状态更改?

我正在尝试使用 React 制作一个简单的游戏,例如紫色宫殿游戏中的紫色对。我有一个名为 的方法clickBtn,它应该在单击时增加计数并在第二次单击时减少,但我不知道为什么该handleClick方法会更改chosen以及clicked状态属性,即使在不使用方法的情况下制作了新状态的副本setState。你能帮我解决这个问题吗?


class GameBoard extends React.Component {

  constructor() {

    super();

    this.state = {

      score: 0,

      time: 0,

      list: [...generateObList(), ...generateObList()],

      count: 0

    };

  }


  handleClick = (id) => {

    this.clickBtn(id);

    const list = this.state.list.slice();

    const current = list.find((a) => a.id === id);

    for (let x of list) {

      if (x.clicked && x.value == list.find((a) => a.id == id).value) {

        x.chosen = true;

        x.clicked = false;

        current.chosen = true;

        current.clicked = false;

        // this.setState((prev) => ({

        //   list: prev.list.map((el) =>

        //     el.id === id ? current : el.value === current.value ? x : el

        //   ),

        //   score: prev.score + 1

        // }));

      }

    }

  };


  clickBtn = (id) => {

    const current = this.state.list.slice().find((e) => e.id === id);

    let deClick = current.clicked;

    current.clicked = !current.clicked;

    console.log(current);

    this.setState(

      (prev) => ({

        list: prev.list.map((el) => (el.id === id ? current : el)),

        count: prev.count + (deClick ? -1 : 1)

      }),

      () => {

        console.log(this.state.count, deClick, current);

      }

    );

  };


  render() {

    const boardStyle = {

      gridTemplateColumns: `repeat(5, 1fr)`,

      gridTemplateRows: `repeat(5,1r)`

    };

    let list = this.state.list.map((n) => (

      <Card

        value={n.value}

        onClick={(e) => {

          this.handleClick(n.id);

        }}

        show={!n.chosen}

      />

    ));

    return (

      <div class="gameBoard" style={boardStyle}>

        {list}

      </div>

    );

  }

}


holdtom
浏览 162回答 1
1回答

斯蒂芬大帝

slice()只需返回数组的浅表副本,因此如果项目是引用类型(对象),则原始和副本都引用相同的数组项目。对于对象切片,将对象引用复制到新数组中。原始数组和新数组都引用同一个对象。如果对象发生更改,则新数组和原始数组都可以看到这些更改。尝试深度复制对象。您可以使用以下方法轻松进行深度复制:JSON.parse(JSON.stringify(arr))也可以试试lodash的cloneDeep()方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript