使用Google Books-books.map对fetch API回调使用fetch并非功能

时间:2018-10-23 19:40:07

标签: javascript reactjs redux google-api google-books

我正在使用React和Google Books API创建一个Web应用程序。我希望可以通过Google图书API搜索图书。当我的提取请求命中Google图书API时,我获得了成功的返回,但回调未解析JSON,并且出现了错误:由组件导致的“未处理的拒绝(TypeError):books.map不是函数”旨在显示搜索结果。问题似乎完全在启动“ NewSearch.search”功能并设置状态的组件中的获取请求和HandleSearchChange函数之间。提取请求返回了数据,但似乎没有在此停止而没有解析响应-响应已经在json中返回-参见https://www.googleapis.com/books/v1/volumes?q=flo

任何帮助将不胜感激!

以下是提取请求:

function search(query, cb) {
  return fetch(`https://www.googleapis.com/books/v1/volumes?q=${query}`, {
    method: 'get',
    headers: {
      'Content-Type': 'application/json'
    },
    success: function(response) {
      console.log(response)
    }
  })

  .then(checkStatus)
  .then(parseJSON)
  .then(cb);
}

function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response;
  }
  const error = new Error(`HTTP Error ${response.statusText}`);
  error.status = response.statusText;
  error.response = response;
  console.log(error);
  throw error;
}

function parseJSON(response) {
  return response.json();
  return console.log(response.json())
}

const NewSearch = { search };
export default NewSearch;

以下是组件:

import react from 'react';
import React, { Component } from 'react';
import NewSearch from '../actions/NewSearch';

const MATCHING_ITEM_LIMIT = 25;

class SearchBooks extends Component {

  constructor(props) {
      super(props);
      this.state = {
        books: [],
        showRemoveIcon: false,
        searchValue: '',
      };

      this.handleSearchChange = this.handleSearchChange.bind(this);
    }

  handleSearchChange = (e) => {
    let value = e.target.value;

    if (this._isMounted) {
      this.setState({
        searchValue: value,
        [e.target.name]: e.target.value,
      });
    }

    if (value === '') {
      this.setState({
        books: [],
        showRemoveIcon: false,
      });
    } else {
      this.setState({
        showRemoveIcon: true,
      });

      NewSearch.search(value, (books) => {
        this.setState({
          books: books
          //books: books.slice(0, MATCHING_ITEM_LIMIT),
        });
      });
    }
  };

  handleSearchCancel = () => {
    this.setState({
      books: [],
      showRemoveIcon: false,
      searchValue: '',
    });
  };

  componentDidMount() {
    this._isMounted = true
  }

  componentWillUnmount() {
    this._isMounted = false
  }

  render() {
    const { showRemoveIcon, books } = this.state;
    const removeIconStyle = showRemoveIcon ? {} : { visibility: 'hidden'};

    const bookRows = books.map((book, idx) =>(
      <tr>
      <td>{book.volumeInfo.title}</td>
      <td>{book.volumeInfo.authors[0]}</td>
      <td>{book.volumeInfo.description}</td>
      </tr>
    ));

    return (
      <div id='book-search'>
        <table className='ui selectable structured large table'>
          <thead>
            <tr>
              <th colSpan='5'>
                <div className='ui fluid search'>
                  <input
                  className='prompt'
                  type='text'
                  placeholder='Search books...'
                  value={this.state.searchValue}
                  onChange={this.handleSearchChange}
                  />
                  <i className='search icon' />
                </div>
                <i
                className='remove icon'
                onClick={this.handleSearchCancel}
                style={removeIconStyle}
                />
              </th>
            </tr>
            <tr>
              <th className='eight wide'>Title</th>
              <th>Authors</th>
              <th> Description</th>
            </tr>
          </thead>
        <tbody>
          {bookRows}
        </tbody>
      </table>
    </div>
  );
 }
}

export default SearchBooks;

1 个答案:

答案 0 :(得分:0)

因为您的Json响应不是数组。 您需要在checkStatus函数中返回response.items(或使用控制台可以检查您想要的内容,但它应该是数组)。然后调用回调函数。