React Native:setState 在调用 try-catch 函数时不起作用

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 信息做些什么:[] 收到我的数据

  1. 您在从 AsyncStorage 获取您的值之前进行 API 调用(我知道这是异步的,但如果您那样做,它的可读性就不太好)。
  2. getScoreFromAPI 没有 return 任何东西,这就是为什么你的 setState 不工作。
  3. 你不需要在这里使用trycatch,promises有自己的错误处理机制(.catch()方法)。
  4. 我认为回调比在代码中使用 .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 后执行,然后将响应存储到 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))
   };