首页 > 解决方案 > ReactJS:调用 fetch() 时未陷入承诺

问题描述

我正在获取的数据有问题。我的 fetch 电话让我没有得到承诺。也就是说,我也不知道我的代码是可能的代码还是好的代码。

我有一个过滤栏,用户可以在其中选择两个日期,这意味着我将这些输入字段放在一个表单中,再次不确定我是否应该这样做,但这样我现在在我的表单上有一个 onSubmit。这个 onSubmit 接受我的函数 handleSubmit,它调用我的 fetch。

import React, { Component } from 'react';
import { SplitButton, Dropdown, Container } from 'react-bootstrap';
import CarCard from '../components/results/CarCard'

//YYYY-MM-DD

class SearchBar extends Component {
    state = {
        fromDate: '',
        toDate: '',
        data: [],
    }

    handleSubmit = event => {
        event.preventDefault();
        this.getData()
    }

    handleChange = event => {
        const target = event.target;
        const value = target.value;
        const name = target.name;
        this.setState({ [name]: value });
    }

    getData = () => {
        const { toDate, fromDate } = this.state
        var url = 'https://www.fenonline.dk/SYS_Backend/api/car/'
        url += fromDate + "/"
        url += toDate
        const data_promise = fetch(url).then(handleHttpErrors)
        data_promise.then(data => this.setState({ data }))
    }

    render() {
        return (
            <Container>
                <Container style={styles.container} fluid={true} >
                    <form onSubmit={this.handleSubmit}>
                        <h5 style={{ color: 'white', }}>Search for your rental here:</h5>
                        <input type="date" label="test" name='fromDate' onChange={this.handleChange} />
                        <input type="date" placeholder={this.state.toDate} name='toDate' onChange={this.handleChange} />
                        <input type='submit' value='search' />
                    </form>
                </Container>
                <Container>
                    {carCardItems(this.state.data) || 'Please wait...'}
                </Container>
            </Container>
        );
    }
}


export default SearchBar;

const carCardItems = data => {
    const items = data.map(c =>
        <CarCard key={c.regno} {...c} />
    );
    return items;
};

function handleHttpErrors(res) {
    if (!res.ok) {
        return Promise.reject({ status: res.status, fullError: res.json() })
    }
    return res.json();
}

标签: reactjsfetch

解决方案


也许您可以重写getData()usingasync/await以更好地捕获未捕获的错误/承诺的所有可能代码路径:

/* Define async function */
getData = async () => {

    /* This try block will encapsulate the fetch logic, and capture all errors
       that can be thrown */
    try {

        const { toDate, fromDate } = this.state
        var url = 'https://www.fenonline.dk/SYS_Backend/api/car/'
        url += fromDate + "/"
        url += toDate

        /* Use await instead of promise.then */
        const response = await fetch(url)

        /* The json() function is async, so use await */
        const json = await response.json()

        /* If response failed, return error data in same format as in your 
           Promise.reject() */
        if(!response.ok) {
            throw { status: response.status, fullError: json } 
        }

        /* Update data with json */
        this.setState({ data : json })
    }
    catch(error) {

        /* Log error to console */
        console.error(error)
    }
}

另请注意,这response.json() 是一个异步方法,这意味着您需要通过await如上所示(或作为 promise; res.json().then(...))调用它。这意味着这样做:

return Promise.reject({ status: res.status, fullError: res.json() })

如您的代码所示,将意味着 的值fullError是一个Promise对象,而不是预期的 JSON 数据


推荐阅读