簡體   English   中英

React Native:調用try-catch函數時setState不起作用

[英]React Native: setState doesn't work when calling try-catch function

我試圖用從另一個文件導入的此代碼調用APP,它工作正常:

import FormData from 'FormData';
import AsyncStorage from '@react-native-community/async-storage';

let formData = new FormData();

formData.append('userId', '1'); // < this is what I want to change
formData.append('key', '***'); //my key

 export function getScoreFromAPI () {
   return fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
                 method : 'POST',
                 headers : {
                   'Accept': 'application/json',
                   'Content-Type': 'multipart/form-data'
                 },
                 body : formData
             } )
       .then((response) => {
          return response.json()
       })
    .catch((error) => console.log("l'erreure est:  " + error))
 }

但是現在我想將我的userId從1更改為Asyncstorage的常量,因此我決定將代碼更改為此:

  constructor(props) {
      super(props)
      this.state = { infos: [], userId: '' }
  }

  componentWillMount() {
    this.getScoreFromAPI().then(data => {
      this.setState({ infos: data })
    });
    console.log(this.state.infos);
    AsyncStorage.getItem(USERID_STORED)
    .then((data) => {
        if (data) {
           this.setState({userId:data})
        }
    });
  }
  async getScoreFromAPI() {
      let formData = new FormData();
      formData.append('userId', this.state.userId);
      formData.append('key', '***'); //my key
    try {
      let response = await fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'multipart/form-data'
        },
        body: formData
      })
      let res = await response.json();

  } catch(error) {
      console.warn("errors are " + error);
  }
};

使用try-catch函數,但是當我在ComponentWillMount()調用getScoreFromAPI() ,無法使用接收到的數據設置狀態,信息中仍然有一個空數組:[]

我的問題:

我如何用第一個文件中asyncstorage中的值替換userId中的'1'?

如果不可能的話,我對setState info:[]所做的操作已顯示了數據

  1. 在從AsyncStorage獲取值之前,您正在執行API調用(我知道這是異步的,但是如果您這樣做的話,它就不太可讀)。
  2. getScoreFromAPI不返回任何內容,這就是為什么setState不起作用的原因。
  3. 您無需在此處使用try and catch ,promise具有自己的錯誤處理機制(.catch()方法)。
  4. 與代碼中使用.then()相比.then()我認為回調更易讀,並且導致的錯誤更少。

這就是我要做的:

constructor(props)
{
    super(props);
    this.state = { infos: [], userId: '' };
    this.onSuccess = this.onSuccess.bind(this);
    this.onFailure = this.onFailure.bind(this);
}

componentWillMount()
{
    // Get userID from local storage, then call your API 
    AsyncStorage.getItem(YOUR_KEY)
        .then(userID=> {
            if (userID)
            {
                this.setState({ userId : userID }, () => {
                    this.getScoreFromAPI(this.onSuccess, this.onFailure); 
                });
            }
        });
}

onSuccess(data)
{
    this.setState({
        infos : data
    });
}

onFailure(err)
{
    console.warn('Error ' + err);
}

getScoreFromAPI(onSuccess, onFailure)
{
    let formData = new FormData();
    formData.append('userId', this.state.userId);
    formData.append('key', '***'); //your key

    fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
        method : 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'multipart/form-data'
        },
        body: formData
    })
    .then(res => res.json())
    .then(json => {
        onSuccess(json);
    })
    .catch(err => {
        onFailure(err);
    });
} 

我已經將您的代碼簡化為一個getScoreFromAPI鏈,在該鏈中,從AsyncStorage獲取userId之后將執行getScoreFromAPI調用,然后將響應存儲到infos狀態,同時在出現錯誤時返回null並將錯誤記錄到控制台。 先前未從getScoreFromAPI返回數據,因此該值將始終為null 我尚未測試此代碼,但這將為您提供一個良好的工作基礎:

import FormData from 'FormData';
import AsyncStorage from '@react-native-community/async-storage';

export default class Test {
    constructor() {
        this.state = {
            infos: null,
            userId: ''
        };
    }

    componentDidMount() {
        AsyncStorage.getItem(this.state.userId)
            .then(userID => {
                this.setState({ userId: userID || '' });
            })
            .then(() => {
                return this.getScoreFromAPI();
            })
            .then(data => {
                this.setState({ infos: data });
            })
            .catch(console.error);
    }

    getScoreFromAPI = () => {
        const formData = new FormData();

        formData.append('userId', this.state.userId);
        formData.append('key', '***'); //my key

        fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
            method: 'POST',
            headers: {
                Accept: 'application/json',
                'Content-Type': 'multipart/form-data'
            },
            body: formData
        })
            .then(response => {
                // use response data here
                return response.json();
            })
            .catch(e => {
                console.error(e);
                return null;
            });
    };
}

終於完成了 我嘗試了一下,它起作用了。 謝謝大家

這是我所做的:

...
const USERID_STORED = "userid_stored";
const GSM_STORED = "gsm_stored";
...
class ScoreList extends React.Component {
  constructor(props) {
      super(props)
      this.state = { infos: [], userId: '', gsmStored: '', }
  }

  componentWillMount() {
    AsyncStorage.getItem(USERID_STORED)
        .then(userId => {
                this.setState({ userId: userId});
                this.getScoreFromAPI(this.state.userId).then(data => {
                  this.setState({ infos: data });
                });
        });
    AsyncStorage.getItem(GSM_STORED)
        .then(gsmStore => {
                this.setState({ gsmStored: gsmStore});
        });
  }

  getScoreFromAPI (userId) {
    let formData = new FormData();
    formData.append('userId', userId);
    formData.append('key', '***');
    return fetch('https://***',{
                   method : 'POST',
                   headers : {
                     'Accept': 'application/json',
                     'Content-Type': 'multipart/form-data'
                   },
                   body : formData
               } )
         .then((response) => {
            return response.json()
         })
      .catch((error) => console.log("l'erreure est:  " + error))
   };

暫無
暫無

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

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