首页 > 解决方案 > 使用 Google Books-books.map 获取 React API 回调不是一个函数

问题描述

我正在使用 React 和 Google Books API 创建一个网络应用程序。我希望可以通过 google 图书 API 搜索图书。当我的 fetch 请求到达 google books API 时,我得到了成功的返回,但是回调没有解析 JSON,并且我得到了错误:“Unhandled Rejection (TypeError): books.map is not a function”由我的组件产生旨在显示搜索结果。问题似乎完全在获取请求和组件内的 HandleSearchChange 函数之间,其中启动了“NewSearch.search”函数并设置了状态。获取请求返回数据,但它似乎在没有解析响应的情况下停在那里 - 响应已经在 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;

标签: javascriptreactjsreduxgoogle-apigoogle-books

解决方案


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


推荐阅读