簡體   English   中英

用React猜數字-在這種情況下使用狀態的正確方法是什么

[英]Guess the number with React - what is the proper way of using state in that case

我的React客戶端應用程序應該猜測1到10000之間的秘密數字。這是我的代碼:

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 ,但是僅以此方式我強迫它工作

您在每次組件執行更新時都設置狀態。.而不是等待請求的回調以查看其較低還是較高

你也應該把狀態轉換的邏輯放在更好的條件中

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}!`);
        }
    }
}

請注意,這里的關鍵是您應該僅在請求返回之后使用setState ..否則,您將無休止地使用setState ..,因為this.state.result將永遠不會更新為成功

setState將導致更新,因此將一遍又一遍地調用componentDidUpdate

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

您需要更好的邏輯來解密是否需要進行更新。 這意味着componentDidUpdate不應執行任何操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM