我正在做石头,纸,剪刀的游戏。在下面的代码中,我有一个上下文文件用于存储全局状态。我还将展示我的选择部分。当用户单击选择组件中的按钮时,将调用setChoices方法,该方法应将用户选择和cpu选择变量设置为全局状态。然后,随后运行cpuScore()方法以增加cpu得分(仅用于说明问题)。 cpu分数会按预期更新,但是选择变量不会更新。如果我不运行cpuScore方法,则选择变量将按预期更新,但显然不会得分。
//上下文文件
import React, { createContext, useState } from 'react';
const GameContext = createContext();
const GameContextProvider = props => {
const [gameItems, setGameItems] = useState(
{userChoice: null, userScore: 0, cpuChoice: null, cpuScore: 0}
);
const setChoices = (userChoice, cpuChoice) => {
setGameItems({...gameItems, userChoice: userChoice, cpuChoice: cpuChoice})
}
const cpuScore = () => {
setGameItems({...gameItems, cpuScore: gameItems.cpuScore + 1})
}
return (
<GameContext.Provider value={{gameItems, setChoices, cpuScore}}>
{ props.children }
</GameContext.Provider>
)
}
export default GameContextProvider;
//选择组件
import React, { useContext } from 'react';
import { GameContext } from '../contexts/GameContext';
const Choices = (props) => {
const { setChoices, cpuScore } = useContext(GameContext);
const getCpuChoice = () => {
const cpuChoices = ['r', 'p', 's'];
const randomIndex = Math.floor((Math.random() * 3));
const cpuDecision = cpuChoices[randomIndex];
return cpuDecision
}
const playGame = (e) => {
const userChoice = e.target.id;
const cpuChoice = getCpuChoice();
setChoices(userChoice, cpuChoice);
cpuScore();
}
return (
<div>
<h1>Make Your Selection</h1>
<div className="choices">
<i className="choice fas fa-hand-paper fa-10x" id="p" onClick={playGame}></i>
<i className="choice fas fa-hand-rock fa-10x" id="r" onClick={playGame}></i>
<i className="choice fas fa-hand-scissors fa-10x" id='s' onClick={playGame}></i>
</div>
</div>
)
我需要更改什么以设置选择和得分的状态?
答案 0 :(得分:2)
由于对dll = CDLL('./test.so')
func = dll.func
func.argtypes = [c_int]
func.restypes = POINTER(c_int*12)
res = func(12)#Here res is an int
res = cast(res, POINTER(c_int*12)).contents
for i in res:
print(i)#Segmentation fault: 11
的调用是异步的,因此您对setState
的两个调用是相互干扰的,后一个将覆盖前一个。
您有一些选择。
setState
或者走得更远,将两个选择和两个分数中的每一个设置为自己的状态值。
const [choices, setChoices] = useState({ user: null, cpu: null });
const [scores, setScores] = useState({ user: 0, cpu: 0);
const setChoices = (userChoice, cpuChoice) => {
const cpuScore = gameItems.cpuScore + 1;
setGameItems({
...gameItems,
userChoice,
cpuChoice,
cpuScore
});
}
:useReducer
答案 1 :(得分:0)
基本上,React不会在您调用setState
之后立即更新。
如果在cpuScore()
之后立即调用setChoices()
,则您正在调用的cpuScore
函数仍然是当前渲染中的函数,而不是在setChoices()
更新之后。因此,cpuScore()
将使用gameItems
的传播值(由于尚未启动setChoices的更新而未更改)的传播值来再次设置状态,这会导致{ {1}}被覆盖。
如果React总是在每个setChoices()
调用之后立即更新,那么性能将很糟糕。 React的作用是将多个setState
调用分批进行一次更新,因此不会重复更新DOM。
setState
我的建议是将这两个状态分开,以免它们被彼此覆盖,或者创建一个新功能来一次处理所有这些更新。