在React中使用变量更新状态

时间:2019-01-29 10:26:11

标签: javascript reactjs

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

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

初始状态

  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>

      );
    }
  }

2 个答案:

答案 0 :(得分:1)

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

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

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

或更常见的模式是检查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>

      );
    }
  }

答案 1 :(得分:1)

JS正在为HTTP调用异步工作。因为React 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},() => {
        this.onImageGet();
      })
    }
    
    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, imgChecked: true })

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

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

      );
    }
  }