Reactjs 为什么这段代码会进入无限循环

Reactjs 为什么这段代码会进入无限循环,reactjs,spring,http,Reactjs,Spring,Http,我有一个React应用程序,它是一个“选择你自己的冒险”的东西,所以它会打印一条消息,然后用户点击一个按钮来决定下一条消息是什么 一些消息没有相关的决策,新消息应该自动打印出来。在我当前的设置中,当用户必须单击按钮弹出下一条消息时,它可以正常工作,但当它应该自动弹出时,它实际上会重复显示下一条消息,直到崩溃 我尝试了很多方法,但都得到了相同的结果,本来只显示一次的消息会多次出现,直到应用程序崩溃 需要注意的是,决策的工作方式是将一个整数列表(每个整数代表下一个子项)发送到服务器,然后使用该列表遍

我有一个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
也设置了状态?