reactjs - 获取请求的响应
问题描述
我有一个 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'));
解决方案
您正在获取无效的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))
}
推荐阅读
- java - 过滤列表哪个属性不包含在另一个列表的属性中
- javascript - 我可以在不使用 javascript 的情况下开始这个简单的 CSS 过渡吗
- office365 - 对于使用 javamail 处理的一个 Office365 邮箱,folder.close(true) 不会清除已删除的电子邮件
- php - MySQL/Eloquent force id by left join 即使为空
- qt - QWidget如何检测鼠标停止移动
- firebase - Flutter:如何在 Firebase 中计算孩子数?
- c - C 如果条件不接受参数
- puppet - Puppet 在代理上创建文件
- php - preg_split 不拆分多个分隔符
- python - 即使我的路径设置正确,Python 也无法在 SublimeText 3 中工作。我应该怎么办?