Reactjs 为什么这段代码会进入无限循环
我有一个React应用程序,它是一个“选择你自己的冒险”的东西,所以它会打印一条消息,然后用户点击一个按钮来决定下一条消息是什么 一些消息没有相关的决策,新消息应该自动打印出来。在我当前的设置中,当用户必须单击按钮弹出下一条消息时,它可以正常工作,但当它应该自动弹出时,它实际上会重复显示下一条消息,直到崩溃 我尝试了很多方法,但都得到了相同的结果,本来只显示一次的消息会多次出现,直到应用程序崩溃 需要注意的是,决策的工作方式是将一个整数列表(每个整数代表下一个子项)发送到服务器,然后使用该列表遍历一棵树——就像我说的,当玩家选择一个按钮,然后根据他们选择的按钮将一个整数添加到列表中时,这种方式工作正常 当没有按钮时,我尝试设置一种方法,只需将Reactjs 为什么这段代码会进入无限循环,reactjs,spring,http,Reactjs,Spring,Http,我有一个React应用程序,它是一个“选择你自己的冒险”的东西,所以它会打印一条消息,然后用户点击一个按钮来决定下一条消息是什么 一些消息没有相关的决策,新消息应该自动打印出来。在我当前的设置中,当用户必须单击按钮弹出下一条消息时,它可以正常工作,但当它应该自动弹出时,它实际上会重复显示下一条消息,直到崩溃 我尝试了很多方法,但都得到了相同的结果,本来只显示一次的消息会多次出现,直到应用程序崩溃 需要注意的是,决策的工作方式是将一个整数列表(每个整数代表下一个子项)发送到服务器,然后使用该列表遍
0
自动添加到列表中(因为如果没有选择,它只有一个子项,即第0个子项)
这是我的代码,当有按钮时使用onDecide
方法,当没有按钮时使用onNonDecide
方法-我最初尝试过使用onDecide
方法,并尝试将事情分开,看看是否有效,但问题相同
还要注意generateDecisions
方法,因为它有一个if
语句,在没有决策时会改变行为
class Home extends Component {
constructor(props) {
super(props);
this.state = {
previouslyPlayed: [],
currentNode: {
id: 1,
text: 'Ah-- what the hell? Stupid thing.',
decisions: [
{
id: 'n1d1',
text: 'Who is this?',
whichChild: 0,
attitude: 0
},
{
id: 'n1d2',
text: 'What the hell yourself.',
whichChild: 0,
attitude: 0
}
],
speaker: 0,
checkpoint: true
},
decisionList: [0]
};
this.onDecide = this.onDecide.bind(this);
this.onNonDecide = this.onNonDecide.bind(this);
}
// Generate the previous messages to be displayed on the screen
generateMessages() {
let currentPrevious = this.state.previouslyPlayed;
if (currentPrevious.indexOf(this.state.currentNode.text) < 0) {
currentPrevious.push(this.state.currentNode.text);
}
return currentPrevious.map((text) =>
<Message key={currentPrevious.indexOf(text)} text={text}/>
);
}
// Generate the current decision that the play must make
generateDecision() {
if (this.state.currentNode.decisions.length <= 0) {
let ignore = this.onNonDecide();
} else {
return <Decision decisions={this.state.currentNode.decisions} onDecide={this.onDecide}/>;
}
}
updatePreviouslyPlayed(text) {
let previouslyPlayed = this.state.previouslyPlayed;
previouslyPlayed.push(text);
this.setState({previouslyPlayed: previouslyPlayed});
}
updateDecisionList(whichChild) {
let decisionList = this.state.decisionList;
decisionList.push(whichChild);
this.setState({decisionList: decisionList});
}
async onDecide(answer) {
//Update the state to reflect the decision made
this.updatePreviouslyPlayed(answer.text);
this.updateDecisionList(answer.whichChild);
let body = { decisionList: this.state.decisionList };
let currentNode = await (await fetch('http://localhost:8080/decide', {
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(body),
})).json();
this.setState({currentNode: currentNode});
}
async onNonDecide() {
this.updateDecisionList(0);
let body = { decisionList: this.state.decisionList }
let currentNode = await (await fetch('http://localhost:8080/decide', {
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(body),
})).json();
this.setState({currentNode: currentNode});
}
render() {
return (
<div>
<Container id={'Application'}>
{this.generateMessages()}
{this.generateDecision()}
</Container>
</div>
);
}
}
export default Home;
class Home扩展组件{
建造师(道具){
超级(道具);
此.state={
先前播放:[],
当前节点:{
id:1,
短信:“啊,怎么回事?蠢东西。”,
决定:[
{
id:'n1d1',
文字:“这是谁?”,
哪个孩子:0,
态度:0
},
{
id:'n1d2',
短信:“你到底在干什么。”,
哪个孩子:0,
态度:0
}
],
发言者:0,
检查点:正确
},
决策列表:[0]
};
this.onDecide=this.onDecide.bind(this);
this.onNonDecide=this.onNonDecide.bind(this);
}
//生成要在屏幕上显示的先前消息
生成消息(){
让currentPrevious=this.state.previously播放;
if(currentPrevious.indexOf(this.state.currentNode.text)<0){
currentPrevious.push(this.state.currentNode.text);
}
返回currentPrevious.map((文本)=>
);
}
//生成剧本必须做出的当前决策
生成决策(){
如果(this.state.currentNode.decisions.length,则问题在于您有一些副作用,这些副作用正在改变在渲染方法中调用的状态
render()函数应该是纯函数,这意味着它不修改组件状态,每次调用时返回相同的结果,并且不直接与浏览器交互。-
例如,这个路径<代码> Read()->这个.EngEngEclipse()-> OnNoDeDead()->这个SETSTATE()> ReDead()/<代码>(并且重复,可能是无限循环,我没有考虑所有可能的路径,仅举一个例子)。
如果没有重新渲染或出现其他意外行为,您可能会遇到的另一个问题是像在generateMessages
中那样的状态变化。先前播放的数组正在使用currentPrevious.push进行变化。问题是,您有一些副作用,这些副作用正在改变当前的状态在render
方法中调用
render()函数应该是纯函数,这意味着它不修改组件状态,每次调用时返回相同的结果,并且不直接与浏览器交互。-
例如,这个路径<代码> Read()->这个.EngEngEclipse()-> OnNoDeDead()->这个SETSTATE()> ReDead()/<代码>(并且重复,可能是无限循环,我没有考虑所有可能的路径,仅举一个例子)。
如果没有重新渲染或出现其他意外行为,您可能会遇到另一个问题,那就是像generateMessages
中那样的变异状态。以前播放的数组正在使用currentPrevious进行变异。按一下我明白您的意思。为什么当用户单击按钮时在所有的onDecide()
方法中,同样的事情没有发生,因为onDecide
也设置了状态?我明白你的意思。为什么当用户单击调用onDecide()
方法的按钮时,同样的事情没有发生,因为onDecide
也设置了状态?