web-dev-qa-db-ja.com

反応JSでフェッチを使用して応答ステータスを処理する

私はReactJSを学び始めました。次に、フェッチを使用してAPIリクエストを作成するときの応答ステータスの処理方法を知りたいです。これが私のコードです:

componentDidMount(){
    this.setState({ isLoading: true })
    var id = this.props.match.params.id        

    const api = `bla/bla/${id}`;

    console.log("start call api")
    fetch(api)
        .then((response) => {
            if(response.status === 200){
                console.log("SUCCESSS")
                return response.json();     
            }else if(response.status === 408){
                console.log("SOMETHING WENT WRONG")
                this.setState({ requestFailed: true })
            }
        })
        .then((data) => {
            this.setState({ isLoading: false, downlines: data.response })
            console.log("DATA STORED")
        })
        .catch((error) => {
            this.setState({ requestFailed: true })
        })
    console.log("end call api")
}

408のテストを行うために接続をオフにしましたが、ロードがまだ表示されます。

render(){
     const { isLoading, requestFailed } = this.state;
      if(requestFailed){
        return( 
            <div className="errorContainer">
                <a className="errorMessage">Opss.. Something went wrong :(</a>
            </div>
        )
    }
}

これが私のブラウザのログです: enter image description here

これを修正するためのアイデアはありますか?

4
kurniawan26

MDNのドキュメントによると:

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

ネットワークエラーが発生した場合、またはサーバー側でCORSが正しく構成されていない場合、fetch()promiseはTypeErrorで拒否しますが、これは通常、権限の問題などを意味します。たとえば、404はネットワークエラーにはなりません。 fetch()が成功したかどうかを正確にチェックするには、promiseが解決されたことを確認し、次にResponse.okプロパティの値がtrueであることを確認します。コードは次のようになります。

fetch('flowers.jpg').then(function(response) {
   if(response.ok) {
     return response.blob();
 }
 throw new Error('Network response was not ok.');
}).then(function(myBlob) { 
   var objectURL = URL.createObjectURL(myBlob); 
   myImage.src = objectURL; 
}).catch(function(error) {
 console.log('There has been a problem with your fetch operation: ', 
 error.message);
});

あなたのコードを見て、私はあなたの408エラーチェックが実行されるとは思いません。実際にはそうは思わなかった。基本的に上記のコードは、リクエストが200ish okの場合はjsonレスポンスを返し、そうでない場合はエラーをスローします。エラーが発生した場合、2番目は実行されず、catchブロックにスローされます。おそらく、isLoading:falseを設定できますか?

また、あなたはAPIの終わりのログステートメントが正しくありません。それはあなたの約束が完了する前に呼ばれています。

5
Charles Owen

応答がOKでない場合にエラーをスローし、catchに直接進みます。

fetch(api)
  .then((response) => {
    if(!response.ok) throw new Error(response.status);
    else return response.json();
  })
  .then((data) => {
    this.setState({ isLoading: false, downlines: data.response });
    console.log("DATA STORED");
  })
  .catch((error) => {
    console.log('error: ' + error);
    this.setState({ requestFailed: true });
  });
5