使用React猜测数字 - 在这种情况下使用状态的正确方法是什么

时间:2018-04-04 16:46:18

标签: javascript reactjs

我的React客户端应用程序应该猜测1到10 000之间的密码。这是我的代码:

import axios from 'axios';
import React, { Component } from 'react';

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

    this.state = {
      number: null,
      result: null,
    };
  }

  componentDidMount() {
    const firstGuess = 5000;
    axios
      .post('http://localhost:3001/number', {
        isNumber: firstGuess,
      })
      .then(response => {
        const { resultCode } = response.data;
        this.setState({ number: firstGuess });
        this.setState({ result: resultCode });
      })
      .catch(error => console.log(error));
  }

  componentDidUpdate(prevProps, prevState) {

    if (prevState !== this.state) {
      if (this.state.result === 'lower') {
        const newNumber = this.state.number - 1;
        axios.post('http://localhost:3001/number', {
          isNumber: newNumber,
        });
        this.setState({ number: newNumber });
      }

      if (this.state.result === 'higher') {
        const newNumber = this.state.number + 1;
        axios.post('http://localhost:3001/number', {
          isNumber: newNumber,
        });
        this.setState({ number: newNumber });
      }

      if (this.state.result === 'success') {
        console.log(`Success! The secret number is ${this.state.number}!`);
      }
    }
  }

  render() {
    return <div>Test</div>;
  }
}

export default GuessEngine;

我收到的错误是这样的:

  

超出最大更新深度。当组件在componentWillUpdate或componentDidUpdate中重复调用setState时,可能会发生这种情况。 React限制嵌套更新的数量以防止无限循环。

因此,如果我不能像这样使用componentDidUpdate,那么使用React Lifecycle Hooks使其正常工作的正确方法是什么?

我的应用已发送1011请求而不是崩溃。

所以使用@John_Ruddell回答我提出了这个解决方案:

 componentDidUpdate() {
    if (this.state.result !== 'success') {
      if (this.state.result === 'lower') {
        const newNumber = this.state.number - 1;
        axios
          .post('http://localhost:3001/number', {
            isNumber: newNumber,
          })
          .then(response => {
            const { resultCode } = response.data;
            this.setState({ result: resultCode, number: newNumber });
          });
      } else if (this.state.result === 'higher') {
        const newNumber = this.state.number + 1;
        axios
          .post('http://localhost:3001/number', {
            isNumber: newNumber,
          })
          .then(response => {
            const { resultCode } = response.data;
            this.setState({ result: resultCode, number: newNumber });
          });
      }
    } else if (this.state.result === 'success') {
      console.log(`Success! The secret number is ${this.state.number}!`);
    } else {
      console.log(`Sorry! Some errors occured!`);
    }
  }

此代码不会比较this.state.number !== prevState.number,但只有通过这种方式我强制它才能正常工作

2 个答案:

答案 0 :(得分:2)

每次组件更新时都会设置状态...而不是等待来自请求的回调以查看其是否更低

你也应该将状态转换的逻辑放入更好的条件

const nextNum = { lower: -1, higher: 1 } // simple mapping of the next guess so you can reduce amount of code
componentDidUpdate(prevProps, prevState) {
    if (this.state.result && this.state.number !== prevState.number) {
        if (nextNum[this.state.result]) {
            // make request with the number
             const newNumber = nextNum[this.state.result]
             axios.post('http://localhost:3001/number', {
                 isNumber: newNumber,
             }).then(response => {
                 const { resultCode } = response.data;
                 this.setState({result: resultCode, number: newNumber})
             }).catch(error => console.log(error));
        } else if (this.state.result === 'success') {
            console.log(`Success! The secret number is ${this.state.number}!`);
        }
    }
}

请注意,这里的关键是你只需要设置状态 AFTER ,否则你将无休止地设置状态..因为this.state.result永远不会被更新为成功< / p>

答案 1 :(得分:1)

setState会导致更新,因此会一次又一次地调用您的componentDidUpdate

componentDidUpdate(prevProps, prevState) { 
  // after each update this will be true and further runing another updates
  if (prevState !== this.state) {  
  }
}

您需要更好的逻辑来破译您是否需要进行更新。在某些时候componentDidUpdate的含义不应该做任何事情。