簡體   English   中英

反應componentDidMount()初始化狀態

[英]React componentDidMount() initializing state

在React的一個小項目上工作,我正在使用Axios從經過測試工作的API中獲取信息。 問題是當我提取數據並嘗試更新組件狀態時,來自API的值沒有被填充到要在組件中呈現的狀態中。

我一直在嘗試使數據處於這種狀態:

  componentDidMount() {
    this.state.databases.forEach(d => {
      axios.get(`http://localhost:3204/customer/${d}/count`).then(value => {
        this.setState({ counts: this.state.counts.push(value.data) });
      });
    });
    console.log(this.state);
  }

以前的版本是這樣寫的:

componentDidMount() {
    let internalCounts = [];
    this.state.databases.forEach(d => {
        axios.get(`http://localhost:3204/customer/${d}/count`).then(value => {
            internalCounts.push(value.data);
        });
    });
    this.setState({count: internalCounts});
}

兩種情況最終都有相同的結果。 狀態永遠不會真正用新的count數組更新。 我懷疑這是由於Axios setState的異步特性引起的。

一種簡單有效的方法來使這兩個人停止比賽?

在第一個版本中,您正確地認為這是由於服務的異步性質所致。 您正在記錄輸出,但這是在服務解決之前發生的。

在第二個(上一個)示例中,您要在狀態解析之前進行設置。 我建議采用以下方法,創建一個promise數組,然后在更新狀態之前等待所有promise解析:

 componentDidMount() { const promises = []; this.state.databases.forEach(d => { promises.push(axios.get(`http://localhost:3204/customer/${d}/count`)); }); Promise.all(promises).then(results => { const internalCounts = []; results.map(result => { internalCounts.push(result.data); }); this.setState({count: internalCounts}); }) } 

設置狀態后不要立即使用console.log ,因為它是異步的。 通過對setState的回調來實現。

this.setState({...}, () => console.log(...))

或使用console.log在渲染方法中檢查狀態

另外,不要對forEach這樣做,而是嘗試一次通過Promise.all一次提出所有請求。

componentDidMount() {
    const promiseArray = this.state.databases.map( d =>
      axios.get(`http://localhost:3204/${d}/count`)
    )
    Promise.all( promiseArray )
      .then( ( results ) => {
        const data = results.map( result => result.data);
        this.setState( prevState => ({
          counts: [ ...prevState.counts, ...data]
        }))
      })
  }

您的代碼有一些問題:

  1. Array.prototype.push(value.data)返回新的長度,而不是新的數組。 因此this.setState({ counts: this.state.counts.push(value.data) }); 正在將state.counts轉換為數字值this.state.counts.length + 1 ,這可能是不希望的。
  2. 如果要打印新狀態,請使用console.log(this.state); 應該放在setState()的回調參數中。
  3. 您的先前版本未在setState之前等待axios調用。 您的想法正確。

問題是我試圖改變狀態。 (我一直對不可變數據感到恐懼...。因此我必須習慣一些東西。)

我的解決方案代碼如下:

componentDidMount(){
    this.state.databases.forEach(d => {
        axios.get(`http://localhost:3204/${d}/count`).then(value => {
            this.setState(prevState => ({
                counts: [...prevState.counts, value.data]
            }));
         });
    });
}

暫無
暫無

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

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