【问题标题】:State is updating but the app isn't updated/状态正在更新,但应用未更新/
【发布时间】:2020-06-23 09:47:14
【问题描述】:

在我的石头剪刀布应用程序中,PcRandomChoice 有时不会在功能中更新并更新为新选择。我的用户选择有时也会发生同样的事情。我究竟做错了什么?我可以使用我的代码框链接进行更新。这是一个状态管理问题吗?当您 console.log 选项时,它显示随机用户选择更新但不更新其他变量。

import React, { Component } from "react";
import ReactInfo from "./ResultInfo";
import { ScoreAlert } from "./Alert";
import { Button, Container, Row, Col } from "react-bootstrap";
import { weapons } from "./data";

const WeaponButton = props => {
  const { name, id, attackAction } = props;
  return (
    <Button
      onClick={() => attackAction(id)}
      className="myButton"
      variant="outline-primary"
      size="md"
    >
      {name}
    </Button>
  );
};

class Counter extends Component {
  constructor(props) {
    super(props);

    this.state = {
      count: 10,
      ran: "",
      id: "",
      temp: Math.floor(Math.random() * 3 + 1),
      draw: {
        score: 0
      },
      user: {
        score: 0,
        choice: ""
      },
      pc: {
        score: 0,
        choice: ""
      },
      roundLimit: 10,
      roundWinner: ""
    };

    this.setWinner = this.setWinner.bind(this);
    this.setWeapon = this.setWeapon.bind(this);
    this.battle = this.battle.bind(this);
    this.attack = this.attack.bind(this);
  }

  setWeapon = (pcId, userId) => {

    const [ pcWeaponName, userWeaponName] = [pcId, userId].map(weaponId => weapons.find(w => w.weaponId === weaponId).name);

    console.log(this.state.pc.choice, pcWeaponName)

    this.setState({
      user: { score: this.state.user.score, choice: userWeaponName },
      pc: { score: this.state.pc.score, choice: pcWeaponName }
    });
  };

  setWinner = (winner = "draw") => {
    const { score, choice } = this.state[winner];

    const newScore = score + 1;

    this.setState({
      roundWinner: winner,
      [winner]: { score: newScore, choice }
    });
  };

  battle = userWeaponId => {
    //Get PC Choice
    const generatePcWeapon = () =>
      [...weapons][Math.floor(Math.random() * weapons.length)];

    const pcWeapon = generatePcWeapon();
    const { weaponId: pcWeaponId, weaknesses = [] } = pcWeapon;
    // Get User Choice

    // Compare IDs
    if (pcWeaponId === userWeaponId) {
      // Update roundWinner to Draw
      this.setWinner();
      // Return
      return;
    }

    // Search for user choice in PC Weaknesses

    this.setWeapon(pcWeaponId, userWeaponId);

    const winner = weaknesses.includes(userWeaponId) ? "user" : "pc";

    this.setWinner(winner);
  };

  attack = id => {
    this.battle(id); // your alert function
  };

  render(props) {
    const { user, pc, roundWinner } = this.state;
    return (
      <>
        <div className="container">
          <Container fluid>
            <Row>
              <Col>
                <h5>Rock, Paper, Scissors</h5>
              </Col>
            </Row>
            <Row>
              <Col>
                <h6> Select Your Weapon </h6>
              </Col>
            </Row>
            {weapons.map(({ name, weaponId }) => {
              return (
                <Row key={weaponId}>
                  <Col>
                    <WeaponButton
                      attackAction={this.attack}
                      id={weaponId}
                      name={name}
                    />
                  </Col>
                </Row>
              );
            })}{" "}
          </Container>
        </div>

        <ReactInfo
          id={user.choice}
          ran={pc.choice}
          roundWinner={roundWinner}
          userPoint={user.score}
          pcPoint={pc.score}
        />
      </>
    );
  }
}

export default Counter;

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    可能是比较浅的问题

    您的状态并不浅,即您在对象中有对象。当检测到状态变化时,会进行浅层比较。要阻止这种情况发生,您应该在设置状态之前复制状态。 一个非常简单的方法是使用 JSON.Stringify 和 JSON.parse。这是 CPU 密集型的,但在这段代码中应该不是问题,它不是很复杂。

    首先检查浅比较是否是实际问题

    setWinner = (winner = "draw") => {
        const { score, choice } = this.state[winner];
    
        const newScore = score + 1;
    
        const stateCopy = JSON.parse(JSON.stringify({
          roundWinner: winner,
          [winner]: { score: newScore, choice }
        }))
    
        this.setState(stateCopy);
      };
    
      setWeapon = (pcId, userId) => {
    
        const [ pcWeaponName, userWeaponName] = [pcId, userId].map(weaponId => weapons.find(w => w.weaponId === weaponId).name);
    
        console.log(this.state.pc.choice, pcWeaponName)
        const stateCopy = JSON.parse(JSON.stringify({
          user: { score: this.state.user.score, choice: userWeaponName },
          pc: { score: this.state.pc.score, choice: pcWeaponName }
        }))
        this.setState(stateCopy);
      };
    

    如果浅比较是问题,让我们改进一下

    一个更好的方法是将你的对象散开,这样它总是新的,你可能也想散开内部对象,因为当使用散布时它也会做浅拷贝。但是您需要在自己的代码中进行测试才能对其进行测试。

    setWinner = (winner = "draw") => {
        const { score, choice } = this.state[winner];
    
        const newScore = score + 1;
    
        const stateCopy = {
          roundWinner: winner,
          [winner]: { score: newScore, choice }
        }
    
        this.setState({...stateCopy});
      };
    
      setWeapon = (pcId, userId) => {
    
        const [ pcWeaponName, userWeaponName] = [pcId, userId].map(weaponId => weapons.find(w => w.weaponId === weaponId).name);
    
        console.log(this.state.pc.choice, pcWeaponName)
        const stateCopy = {
          user: { score: this.state.user.score, choice: userWeaponName },
          pc: { score: this.state.pc.score, choice: pcWeaponName }
        }
        this.setState({...stateCopy});
      };
    

    【讨论】:

    • 不,不幸的是,这并没有解决,但谢谢
    猜你喜欢
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    相关资源
    最近更新 更多