我正在尝试查询应该返回与用户查询匹配的书籍的json对象的API。
问题是我在代码中得到的是一个承诺,而不是一个json对象。
在Chrome开发工具中,我可以看到我从服务器获得了一个带有json类型的200响应,而对象就是我希望收到的内容。
当我console.log
查询结果时,它会作为承诺出现。
对此很新,但我的理解是,在我的searchBook
组件中使用查询字符串设置SearchBooks
时,我应该获取一个json对象
SearchBooks.js
import React, { Component } from 'react'
import * as BooksAPI from './utils/BooksAPI'
// import Book from './Book';
export default class SearchBooks extends Component {
state = {
query: ''
}
updateQuery = (query) => {
this.setState(() => ({
query: query
}))
}
clearQuery = () => {
this.updateQuery('')
}
searchBook = (query) => {
return BooksAPI.search(query)
}
searchFromQuery = () => {
return this.state.query.split(' ').map((b) => (
this.searchBook(b)
))
}
render() {
const { query } = this.state
// const { onUpdateShelf } = this.props
const showingBooks = query === ''
? 'No results'
: this.searchFromQuery()
return(
<div className="search-books">
<div className="search-books-bar">
<a className="close-search" >Close</a>
<div className="search-books-input-wrapper">
<input
type="text"
placeholder="Search by title, author or subject"
value={query}
onChange={(event) => this.updateQuery(event.target.value)}
/>
</div>
</div>
<div className="search-books-results">
<ol className="books-grid">
{/* <Book
key={book.id}
book={book}
updateShelf={onUpdateShelf} /> */}
</ol>
</div>
</div>
)
}
}
API Request Function
export const search = (query) =>
fetch(`${api}/search`, {
method: 'POST',
headers: {
...headers,
'Content-Type': 'application/json'
},
body: JSON.stringify({ query })
}).then(res => res.json())
.then(data => data.books)
Result of console.log(this.searchFromQuery())
[Promise]
0
:
Promise
__proto__
:
Promise
[[PromiseStatus]]
:
"resolved"
[[PromiseValue]]
:
Array(20)
length
:
1
__proto__
:
Array(0)
Request/Response Headers
// Request
POST /search HTTP/1.1
Host: reactnd-books-api.xxxxx
Connection: keep-alive
Content-Length: 13
Accept: application/json
Origin: http://localhost:3000
Authorization: 2nhixsfp
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
Content-Type: application/json
Referer: http://localhost:3000/search
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
// Response
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
ETag: W/"78c1-CfIO/Nda/QZYUxfCqeekUjLL3SU"
Date: Wed, 23 May 2018 15:15:00 GMT
Transfer-Encoding: chunked
Content-Encoding: gzip
X-Berlioz-Country: GB
Access-Control-Allow-Headers: X-Berlioz-Country
Access-Control-Expose-Headers: X-Berlioz-Country
Strict-Transport-Security: max-age=300;
Request URL: https://xxxx.com/search
Request Method: POST
Status Code: 200 OK
Remote Address: xxxxx
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: X-Berlioz-Country
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Berlioz-Country
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Date: Wed, 23 May 2018 15:15:00 GMT
ETag: W/"78c1-CfIO/Nda/QZYUxfCqeekUjLL3SU"
Strict-Transport-Security: max-age=300;
Transfer-Encoding: chunked
X-Berlioz-Country: GB
X-Powered-By: Express
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Authorization: 2nhixsfp
Connection: keep-alive
Content-Length: 13
Content-Type: application/json
Host: reactnd-books-api.udacity.com
Origin: http://localhost:3000
Referer: http://localhost:3000/search
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
{query: "p"}
query
:
"p"
答案 0 :(得分:1)
对来自res.json()
的响应调用fetch
会返回以JSON格式解析为请求正文的承诺。您应该做的是使用来自请求的数据设置一些状态。你可以这样做:
export default class SearchBooks extends Component {
state = {
query: '',
books: []
}
updateQuery = (query) => {
this.setState(() => ({
query: query
}))
}
clearQuery = () => {
this.updateQuery('')
}
searchBook = (query) => {
// Instead of returning the promise, you add the response data to the state
BooksAPI.search(query)
.then(books => this.setState(prevState => ({ books: prevState.books.concat(books)})));
}
render() {
const { query } = this.state
// const { onUpdateShelf } = this.props
const showingBooks = query === ''
? 'No results'
: this.searchBook(query)
return(
<div className="search-books">
<div className="search-books-bar">
<a className="close-search" >Close</a>
<div className="search-books-input-wrapper">
<input
type="text"
placeholder="Search by title, author or subject"
value={query}
onChange={(event) => this.updateQuery(event.target.value)}
/>
</div>
</div>
<div className="search-books-results">
<ol className="books-grid">
{this.state.books.map(book => <Book key{book.id} book={book} updateShelf={onUpdateShelf} />)}
</ol>
</div>
</div>
)
}
}
这是一般的想法,只需从promise中获取值并将其设置为state。您可以根据需要对其进行扩展。