首页 > 解决方案 > 在react中设置ajax的结果

问题描述

为什么ajax请求的结果没有在默认为[]的Library中设置。当Library的数据静态设置时不会有问题:

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', .....]

但是将是动态的,数据将通过 ajax 请求从另一个页面发送到该页面。我应该怎么做才能在Library中设置 ajax 请求的结果。

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

解决方案


首先,除非你真的真的必须,尽量避免在 React 中使用 jQuery。这只会导致巨大的头痛。

您需要将该 Ajax 请求移出构造函数并移到您的componentDidMount方法中。例如:

class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            Library: [],
        }
    }

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

推荐阅读