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

问题描述 投票:0回答:2

我的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,但只有这样我强迫它才能工作

javascript reactjs
2个回答
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}!`);
        }
    }
}

注意这里的关键是你应该只在请求返回后设置State ..否则你将无休止地设置State ..因为this.state.result将永远不会更新为成功


1
投票

setState将导致更新,所以你的componentDidUpdate将被反复调用:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.