You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native石头剪刀布游戏result变量未实时更新问题求助

石头剪刀布游戏结果实时显示问题解决

问题描述

开发React Native石头剪刀布游戏时,功能整体正常,但result变量无法实时显示当前对局结果,总是显示上一局的结果。例如:

  • 当我选择石头且电脑也选择石头时,本该显示平局,但界面无显示;
  • 当我再次选择石头而电脑选择纸时,result却显示上一局的平局结果。

原代码

const RockPaperScissors = () => {

const [userOption, setUserOption] = useState("user")
const [computerOption, setComputerOption] = useState("computer")
const [result, setResult] = useState("")


const options = ["paper", "rock", "scissors"]



const rockOption = () => {
    let choice = Math.floor(Math.random()*3)
    setComputerOption(options[choice])
}


const resultRock = () => {

    setUserOption("rock")

    if (computerOption == userOption){
        setResult("tie")
    } else {
        setResult("no tie")
    }

}

const combineRock = () => {
    rockOption() 
    resultRock() 
}

const RenderComputer = () => {
    if (computerOption == "paper") {
        return (
            <FontAwesome name="hand-paper-o" size={70} color="black" />
        )
    }
    if (computerOption == "rock") {
        return (
            <FontAwesome name="hand-rock-o" size={70} color="black" />

        )
    }
    if (computerOption == "scissors") {
        return (
            <FontAwesome name="hand-scissors-o" size={70} color="black" />
        )
    }


}


return (
    <View style={styles.container} >
        <Text style={styles.title} >
            Rock - Paper - Scissors
        </Text>
        <View style={styles.containerGame} >
            <View style={styles.computer} >
                <Text>Computer Option</Text>
                <RenderComputer/>
            </View>
            <Text>Result: {result}</Text>
            <View style={styles.user} >
                <Text>Your Option</Text>
                <FontAwesome name="hand-rock-o" size={70} color="black" onPress={combineRock}/>
                {/* <FontAwesome name="hand-paper-o" size={70} color="black" onPress={rockOption}/>
                <FontAwesome name="hand-scissors-o" size={70} color="black" onPress={rockOption}/> */}
            </View>
        </View>
    </View>
)
}

问题原因

React的useState更新是异步的。在combineRock中,先调用rockOption设置computerOption,紧接着调用resultRock时,computerOption的新值还未生效,resultRock使用的是更新前的旧状态,导致结果计算错误,显示上一局的结果。

解决方案

方案1:使用useEffect监听状态变化计算结果

通过useEffect监听userOption和computerOption的变化,每当这两个状态更新时,自动计算并更新result:

import { useState, useEffect } from 'react';

const RockPaperScissors = () => {
  const [userOption, setUserOption] = useState("")
  const [computerOption, setComputerOption] = useState("")
  const [result, setResult] = useState("")

  const options = ["paper", "rock", "scissors"]

  // 监听状态变化,自动计算结果
  useEffect(() => {
    if (userOption && computerOption) {
      setResult(userOption === computerOption ? "tie" : "no tie")
    }
  }, [userOption, computerOption])

  const rockOption = () => {
    let choice = Math.floor(Math.random()*3)
    setComputerOption(options[choice])
  }

  const combineRock = () => {
    setUserOption("rock")
    rockOption()
  }

  const RenderComputer = () => {
    if (computerOption == "paper") {
      return <FontAwesome name="hand-paper-o" size={70} color="black" />
    }
    if (computerOption == "rock") {
      return <FontAwesome name="hand-rock-o" size={70} color="black" />
    }
    if (computerOption == "scissors") {
      return <FontAwesome name="hand-scissors-o" size={70} color="black" />
    }
    return null
  }

  return (
    <View style={styles.container} >
      <Text style={styles.title} >Rock - Paper - Scissors</Text>
      <View style={styles.containerGame} >
        <View style={styles.computer} >
          <Text>Computer Option</Text>
          <RenderComputer/>
        </View>
        <Text>Result: {result}</Text>
        <View style={styles.user} >
          <Text>Your Option</Text>
          <FontAwesome name="hand-rock-o" size={70} color="black" onPress={combineRock}/>
          {/* <FontAwesome name="hand-paper-o" size={70} color="black" onPress={() => {setUserOption("paper"); rockOption()}}/>
          <FontAwesome name="hand-scissors-o" size={70} color="black" onPress={() => {setUserOption("scissors"); rockOption()}}/> */}
        </View>
      </View>
    </View>
  )
}

方案2:合并逻辑,直接使用最新值计算结果

将用户选择、电脑选择、结果计算合并到一个函数中,直接用生成的电脑选择值计算结果,避免依赖异步更新的state:

const RockPaperScissors = () => {
  const [userOption, setUserOption] = useState("")
  const [computerOption, setComputerOption] = useState("")
  const [result, setResult] = useState("")

  const options = ["paper", "rock", "scissors"]

  const handleUserChoice = (choice) => {
    setUserOption(choice)
    // 生成电脑选择
    const computerChoice = options[Math.floor(Math.random()*3)]
    setComputerOption(computerChoice)
    // 直接计算结果
    setResult(choice === computerChoice ? "tie" : "no tie")
  }

  const RenderComputer = () => {
    if (computerOption == "paper") {
      return <FontAwesome name="hand-paper-o" size={70} color="black" />
    }
    if (computerOption == "rock") {
      return <FontAwesome name="hand-rock-o" size={70} color="black" />
    }
    if (computerOption == "scissors") {
      return <FontAwesome name="hand-scissors-o" size={70} color="black" />
    }
    return null
  }

  return (
    <View style={styles.container} >
      <Text style={styles.title} >Rock - Paper - Scissors</Text>
      <View style={styles.containerGame} >
        <View style={styles.computer} >
          <Text>Computer Option</Text>
          <RenderComputer/>
        </View>
        <Text>Result: {result}</Text>
        <View style={styles.user} >
          <Text>Your Option</Text>
          <FontAwesome name="hand-rock-o" size={70} color="black" onPress={() => handleUserChoice("rock")}/>
          {/* <FontAwesome name="hand-paper-o" size={70} color="black" onPress={() => handleUserChoice("paper")}/>
          <FontAwesome name="hand-scissors-o" size={70} color="black" onPress={() => handleUserChoice("scissors")}/> */}
        </View>
      </View>
    </View>
  )
}

说明

两种方案都能解决延迟显示的问题:

  • 方案1适合状态更新逻辑分散的场景,利用useEffect自动同步结果;
  • 方案2逻辑更集中,代码更简洁,适合将操作合并管理的场景。

内容的提问来源于stack exchange,提问作者Tommy Solano Peñafiel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:05:26