首页 > 解决方案 > 获取请求的响应

问题描述

我有一个 json 文件,我想通过fetch()请求调用它。我的json是这样的:

[{'id': '5c0b6cd9e1382352759fbc25', 'hotelinfo': {'hotelsearch': {'realname': 'Korston Hotel Moscow'}},{'id': '5c0b6cd9e1382352759fbc24', 'hotelinfo': {'hotelsearch': {'realname': 'Lavanta Hotel'}},{'id': '5c0b6cd9e1382352759fbc28', 'hotelinfo': {'hotelsearch': {'realname': 'Stanpoli Hotel'}},.....]

但我的 setState 函数永远不会执行。

 componentDidMount() {
  fetch('/json.bc')
 .then(response => response.json())
 .then(data => {
        this.setState(state => ({
            ...state,
            Library: data
        }), () => {
            this.reorganiseLibrary()
        })
 })
 .catch(error => console.error(error))
 }

并且有这个错误:SyntaxError: "JSON.parse: expected property name or '}' at line 1 column 3 of the JSON data"。

编辑:

库必须包含 json.bc 文件

Library:[{'id': '5c0b6cd9e1382352759fbc25', 'hotelinfo': {'name': 'Korston Hotel', 'hotelsearch': {'realname': 'Korston Hotel Moscow', 'hotelid': 1011702.0, 'hotelimage': 'htl207110100001', 'countryid': 1002035.0, 'ecountryname': 'Russia', 'countryname': '', 'cityid': 1182348.0, 'ecityname': 'Moscow', 'cityname': '', 'star': 4.0, 'services': 'H.B', 'desc': ' ', 'enable': '1', 'delete': '0'}, 'information': {'viewname': ''}, 'validatedate': {'fdate': '1397-12-01', 'tdate': '1397-12-29', 'tdateid': 10592.0, 'fdateid': 10564.0}}, 'families': [{'availablerooms': [{'info': {'room': 'Single', 'cost': 2400.0, 'availability': 'onrequest', 'withbed': 0.0, 'withoutbed': 0.0, 'adults': 1.0, 'infant': 0.0, 'roomid': '1011702_483587', 'double': '0'}}], 'optionId': '1011702_483587@@@5c0b6cd9e1382352759fbc25', 'totalPrice': 2400.0, 'services': 'H.B', .....]

但是将是动态的,数据将通过获取请求从另一个页面发送到该页面。

class App extends React.Component {
    constructor(props) {
        super();
        this.state = {
            Library: [],
            library: null,
            perPage: 1,
            currentPage: 1,
            maxPage: null,
            filter: ""
        };

    }
 componentDidMount() {
  fetch('/json.bc')
 .then(response => response.json())
 .then(data => {
        this.setState(state => ({
            ...state,
            Library: data
        }), () => {
            this.reorganiseLibrary()
        })
 })
 .catch(error => console.error(error))
 }
    // Calculates the library
    reorganiseLibrary = () => {
        const { filter, perPage, Library } = this.state;
        let library = Library;
        console.log(Library) //There is no result here//
        if (filter !== "") {
            library = library.filter(item =>
                item.hotelinfo.hotelsearch.realname.toLowerCase().includes(filter)
            );
        }

        library = _.chunk(library, perPage);

        this.setState({
            library,
            currentPage: 1,
            maxPage: library.length === 0 ? 1 : library.length
        });
    };

    // Previous Page
    previousPage = () =>
        this.setState(prevState => ({
            currentPage: prevState.currentPage - 1
        }));

    // Next Page
    nextPage = () =>
        this.setState(prevState => ({
            currentPage: prevState.currentPage + 1
        }));

    // handle filter
    handleFilter = evt =>
        this.setState(
            {
                filter: evt.target.value.toLowerCase()
            },
            () => {
                this.reorganiseLibrary();
            }
        );

    // handle per page
    handlePerPage = (evt) =>
        this.setState({
            perPage: evt.target.value
        }, () => this.reorganiseLibrary());

    // handle render of library
    renderLibrary = () => {
        const { library, currentPage } = this.state;
        if (!library || (library && library.length === 0)) {
            return <div>No results</div>;
        }
        return library[currentPage - 1].map(item => (
            <div key={item.hotelinfo.hotelsearch.realname}>{item.hotelinfo.hotelsearch.realname}</div>
        ));
    };

    render() {
        const { library, currentPage, perPage, maxPage } = this.state;
        return (
            <div className="library">
                <h1>Library</h1>
                <div className="d-flex">
                    <div className="flex-fill">
                        <label className="library__filter-label">Filter</label>
                        <input value={this.state.filter} onChange={this.handleFilter} />
                    </div>
                    <div className="flex-fill text-right">
                        <label className="library__per-page-label">Per page</label>
                        <input placeholder="per page" value={this.state.perPage} onChange={this.handlePerPage} />
                    </div>
                </div>
                <div className="library__book-shelf">
                    {this.renderLibrary()}
                </div>
                <div className="d-flex">
                    <div className="flex-fill">
                        {currentPage !== 1 && (
                            <button onClick={this.previousPage}>Previous</button>
                        )}
                    </div>
                    <div className="flex-fill text-right">
                        {(currentPage < maxPage) && (
                            <button onClick={this.nextPage}>Next</button>
                        )}
                    </div>
                </div>
                <div className="library__page-info text-right">
                    {this.state.currentPage} of {this.state.maxPage}
                </div>
            </div>
        );
    }
}
ReactDOM.render(<App />, document.getElementById('root'));

编辑2

class App extends React.Component {
    constructor(props) {
        super();
        this.state = {
            Library: [],
            library: null,
            perPage: 1,
            currentPage: 1,
            maxPage: null,
            filter: ""
        };
        $.ajax({
            url: "/json.bc",
            type: "post",
            data: {
                cityid: "1182348",
                rooms: JSON.stringify({ "rooms": [{ "adultcount": "1", "childcountandage": "0" }] }),
            },
            success: (result) => {
                this.setState({ Library: eval(result) });
            }
        })
    }
    componentDidMount() {
        this.reorganiseLibrary();
    }
    // Calculates the library
    reorganiseLibrary = () => {
        const { filter, perPage, Library } = this.state;
        let library = Library;
        console.log(Library) //There is no result here//
        if (filter !== "") {
            library = library.filter(item =>
                item.hotelinfo.hotelsearch.realname.toLowerCase().includes(filter)
            );
        }

        library = _.chunk(library, perPage);

        this.setState({
            library,
            currentPage: 1,
            maxPage: library.length === 0 ? 1 : library.length
        });
    };

    // Previous Page
    previousPage = () =>
        this.setState(prevState => ({
            currentPage: prevState.currentPage - 1
        }));

    // Next Page
    nextPage = () =>
        this.setState(prevState => ({
            currentPage: prevState.currentPage + 1
        }));

    // handle filter
    handleFilter = evt =>
        this.setState(
            {
                filter: evt.target.value.toLowerCase()
            },
            () => {
                this.reorganiseLibrary();
            }
        );

    // handle per page
    handlePerPage = (evt) =>
        this.setState({
            perPage: evt.target.value
        }, () => this.reorganiseLibrary());

    // handle render of library
    renderLibrary = () => {
        const { library, currentPage } = this.state;
        if (!library || (library && library.length === 0)) {
            return <div>No results</div>;
        }
        return library[currentPage - 1].map(item => (
            <div key={item.hotelinfo.hotelsearch.realname}>{item.hotelinfo.hotelsearch.realname}</div>
        ));
    };

    render() {
        const { library, currentPage, perPage, maxPage } = this.state;
        return (
            <div className="library">
                <h1>Library</h1>
                <div className="d-flex">
                    <div className="flex-fill">
                        <label className="library__filter-label">Filter</label>
                        <input value={this.state.filter} onChange={this.handleFilter} />
                    </div>
                    <div className="flex-fill text-right">
                        <label className="library__per-page-label">Per page</label>
                        <input placeholder="per page" value={this.state.perPage} onChange={this.handlePerPage} />
                    </div>
                </div>
                <div className="library__book-shelf">
                    {this.renderLibrary()}
                </div>
                <div className="d-flex">
                    <div className="flex-fill">
                        {currentPage !== 1 && (
                            <button onClick={this.previousPage}>Previous</button>
                        )}
                    </div>
                    <div className="flex-fill text-right">
                        {(currentPage < maxPage) && (
                            <button onClick={this.nextPage}>Next</button>
                        )}
                    </div>
                </div>
                <div className="library__page-info text-right">
                    {this.state.currentPage} of {this.state.maxPage}
                </div>
            </div>
        );
    }
}
ReactDOM.render(<App />, document.getElementById('root')); 

标签: reactjs

解决方案


您正在获取无效的JSON 字符串。如果后端 API 无法更改(正如您在评论中提到的),您可以通过替换无效的 JSON 字符以“hacky”方式解决您的问题,这是一个示例:

 componentDidMount() {

     fetch('/json.bc')
    .then(response => response.text())
    .then(text => {
        var data = JSON.parse(text.replace(/\'/g, '"'))

        this.setState(state => ({
            ...state,
            Library: data
        }), () => {
            this.reorganiseLibrary()
        })
     }).catch(error => console.error(error))
 }

推荐阅读