首页 > 解决方案 > 在 React 中使用变量更新状态

问题描述

我正在尝试破解我的状态未更新的特殊问题。我有一个通过 Axios 调用 NASA api 的函数,它运行良好。当前datePicked状态默认为空,这意味着 GET 请求默认为当前日期。我要添加功能以生成随机日期(函数onRandomDateClick),一切正常。

然后我想datePicked用生成的日期更新状态,然后运行onImageGet保存 axios 请求的函数。

初始状态

  class Photo extends Component {
    state = {
      apiUrl: 'XXXXXXXX',
      apiKey: 'XXXXXXXX',
      image: null,
      imgChecked: false,
      datePicked: ""
    };

生成随机日期、日志变量和状态。状态当前显示为空白。this.setState 不起作用。

    onRandomDateClick = (e) => {
      function randomDate(start, end) {
        return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
      }
      let randomDateResult = randomDate(new Date(2012, 0, 1), new Date())
      let datePicked = randomDateResult.toISOString().slice(0,10);
      this.setState({datePicked})
      console.log("variable is " + datePicked);
      console.log("state is " + this.state.datePicked);
      this.onImageGet();
    }

Axios 调用这里有状态

    onImageGet = e => {
      axios.get(`${this.state.apiUrl}?api_key=${this.state.apiKey}&date=${this.state.datePicked}`)
      //response always starts res.data
          .then(res => {
            const image = res.data;
            this.setState({ image })
          })
          this.setState({imgChecked: true})
    }


    render() {
      ...blah blah...
      return (
        <div className="photo">        

         ... blah blah blah ...
        </div>

      );
    }
  }

标签: javascriptreactjs

解决方案


问题是这setState是异步的,因此当您onImageGet在设置状态后立即调用时,状态尚未更新,您可以访问前一个状态。

您可以使用setState支持在状态更新后调用的回调方法。

this.setState({datePicked}, this.onImageGet)

或更常见的模式是检查 the 中的相关更改componentDidUpdate并在那里调用this.onImageGet

  class Photo extends Component {
    state = {
      apiUrl: 'XXXXXXXX',
      apiKey: 'XXXXXXXX',
      image: null,
      imgChecked: false,
      datePicked: ""
    };


    onRandomDateClick = (e) => {
      function randomDate(start, end) {
        return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
      }
      let randomDateResult = randomDate(new Date(2012, 0, 1), new Date())
      let datePicked = randomDateResult.toISOString().slice(0,10);
      this.setState({datePicked})
      console.log("variable is " + datePicked);
      console.log("state is " + this.state.datePicked);
    }

    onImageGet = e => {
      axios.get(`${this.state.apiUrl}?api_key=${this.state.apiKey}&date=${this.state.datePicked}`)
      //response always starts res.data
          .then(res => {
            const image = res.data;
            this.setState({ image })
          })
          this.setState({imgChecked: true})
    }

    componentDidUpdate(prevProps, prevState){
      if (prevState.datePicked !== this.state.datePicked){
        this.onImageGet();
      }
    }

    render() {
      ...blah blah...
      return (
        <div className="photo">        
         ... blah blah blah ...
        </div>

      );
    }
  }

推荐阅读