Reactjs 调用React函数时出现TypeError异常

Reactjs 调用React函数时出现TypeError异常,reactjs,jsx,Reactjs,Jsx,我正在重构一个小应用程序,它可以将书籍整理到各自的书架上。我已将JSX提取到一个Book.js文件中,以处理每个图书对象的渲染,并调用updateself方法在书架之间移动图书 为此,我从App.js导出了updateself函数,并将其导入Book.js组件,该组件嵌入到ListBooks中,该组件使用map函数将每个Book对象传递到Book进行渲染 我遇到的问题是,当Book中的onChange处理程序启动时,我得到以下异常: TypeError:对象(…)不是函数 17 | <

我正在重构一个小应用程序,它可以将书籍整理到各自的书架上。我已将
JSX
提取到一个
Book.js
文件中,以处理每个图书对象的渲染,并调用
updateself
方法在书架之间移动图书

为此,我从
App.js
导出了
updateself
函数,并将其导入
Book.js
组件,该组件嵌入到
ListBooks
中,该组件使用
map
函数将每个Book对象传递到
Book
进行渲染

我遇到的问题是,当
Book
中的
onChange
处理程序启动时,我得到以下异常:

TypeError:对象(…)不是函数

  17 | <div className="book-top">
  18 |     <div className="book-cover" style={{ width: 128, height: 193, backgroundImage: `url(${book.imageLinks.thumbnail})` }}></div>
  19 |         <div className="book-shelf-changer"> 
> 20 |             <select value={book.shelf} onChange={(e) => updateShelf(book, e.target.value)}>
  21 |                 <option value="none" disabled >Move to...</option>
  22 |                 <option value="currentlyReading" >Currently Reading</option>
  23 |                 <option value="wantToRead" >Want to Read</option>
ListBooks.js

import React, { Component } from 'react'
import ListBooks from './ListBooks'
import SearchBooks from './SearchBooks'
import * as BooksAPI from './utils/BooksAPI'
import { Route } from 'react-router-dom'

class BooksApp extends Component {
  state = {
    books: []
  }

  componentDidMount() {
    BooksAPI.getAll()
    .then((books) => {
      this.setState(() => ({
        books
      }))
    })
  }

  updateShelf(book, shelf) {
    this.state.books.forEach(b => {
      if(b.id === book.id && shelf !== '' && shelf !== 'none') {
        b.shelf = shelf
        this.setState((currentState) => ({
          books: currentState.books
        }))
        BooksAPI.update(book, shelf)
      }
    });
  }

  render() {
    return (
      <div>
        <Route exact path='/' render={() => (
          <ListBooks
          books={this.state.books}
          onUpdateShelf={this.updateShelf}
          />
        )} />
        <Route exact path='/search' render={() => (
          <SearchBooks
          books={this.state.books}
          />
        )} />
      </div>
    )
  }
}
export default BooksApp
export const updateShelf = updateShelf;
import React, { Component } from 'react';
import PropTypes from 'prop-types'
import './App.css'
import { Link } from 'react-router-dom'
import Book from './Book'

const shelves = [
  {
    key: 'currentlyReading',
    name: 'Currently Reading'
  },
  {
    key: 'wantToRead',
    name: 'Want To Read'
  },
  {
    key: 'read',
    name: 'Read'
  }
];

class ListBooks extends Component {

    static propTypes = {
       books: PropTypes.array.isRequired
    }

    render() {

        const { books } = this.props

        function getBooksForShelf(shelfKey) {
          return books.filter(book => book.shelf === shelfKey);
        }

        return(
            <div className="app">
              <div className="list-books">
                <div className="list-books-title">
                  <h1>My Reads</h1>
                </div>
                <div className="list-books-content">
                  <div>
                    { shelves.map((shelf) => (
                      <div key={shelf.key} className="bookshelf">
                        <h2 className="bookshelf-title">{shelf.name}</h2>
                          <div className="bookshelf-books">
                            <ol className="books-grid">
                        <li>
                          { getBooksForShelf(shelf.key).map((book) => (
                            <Book key={book.id} book={book}/>
                            ))}
                          </li>
                        </ol>
                        </div> 
                      </div>
                    )) }
                  </div>
                </div>
                <Link
                    to='/search'
                    className="open-search">
                    Find a Book
                </Link>
              </div>
            }
          </div>
        )
    }
}

export default ListBooks
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { updateShelf } from './App'

class Book extends Component {

    static propTypes = {
        book: PropTypes.object.isRequired
    }    

    render() {

        const { book } = this.props

        return(
            <div key={book.id} className="book">
                <div className="book-top">
                    <div className="book-cover" style={{ width: 128, height: 193, backgroundImage: `url(${book.imageLinks.thumbnail})` }}></div>
                        <div className="book-shelf-changer"> 
                            <select value={book.shelf} onChange={(e) => updateShelf(book, e.target.value)}>
                                <option value="none" disabled >Move to...</option>
                                <option value="currentlyReading" >Currently Reading</option>
                                <option value="wantToRead" >Want to Read</option>
                                <option value="read" >Read</option>
                                <option value="none" >None</option>
                            </select>
                            </div>
                        </div>
                     <div className="book-title">{book.title}</div>
                <div className="book-authors">{book.authors}</div>
            </div>
        )
    }
}

export default Book

您正在导出
export const updateself=updateself
。但是
updateself
是组件的一部分,所以它很可能是未定义的。如果您计划导出该方法,则应将其移到类之外;如果您希望它更改组件,则应将其作为道具传递。

完成了该工作。但我必须通过ListBooks.js组件传递它。有没有办法将其直接传递给Book.js?您可以使用React上下文API。但我建议现在通过ListBooks.js传递它。