Reactjs 反应未定义的错误

Reactjs 反应未定义的错误,reactjs,Reactjs,完整代码 我得到了未定义的udpateShelf的错误,但是Changeshelf被导入,并且在函数中分配了属性,我很困惑,为什么我仍然得到未定义的错误?我觉得我没有完全理解react是如何通过组件传递道具的,如果有人能更好地解释一下,我觉得这将有助于我为这个应用程序创建不同的组件或功能 书架 import React, { Component } from 'react' import * as BooksAPI from './BooksAPI' import PropTypes from

完整代码

我得到了未定义的udpateShelf的错误,但是Changeshelf被导入,并且在函数中分配了属性,我很困惑,为什么我仍然得到未定义的错误?我觉得我没有完全理解react是如何通过组件传递道具的,如果有人能更好地解释一下,我觉得这将有助于我为这个应用程序创建不同的组件或功能

书架

import React, { Component } from 'react'
import * as BooksAPI from './BooksAPI'
import PropTypes from 'prop-types'
import Books from './Books.js'
import logo from '../icons/logo.svg'
import { Link } from 'react-router-dom'
import ChangeShelf from "./ChangeShelf.js"

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

export default class Bookshelf extends Component {

static propTypes = {
  book: PropTypes.object.isRequired,
  books: PropTypes.array.isRequired,
  updateShelf: PropTypes.func.isRequired
}

render() {
  const { book, books, shelfkey } = this.props;

  return (

  <div className="list-books">
      <div className="react-app">
        <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <h1 className="App-title">React bookshelf app</h1>
        </header>
      </div>

        <div className="list-books-title">
          <h1>my bookshelf</h1>
        </div>

    <div className="list-books-content">
      {shelves.map(shelf => (
        <div key={ shelf.key } className="bookshelf">
          <h2 className="bookshelf-title">{ shelf.name }</h2>

          { updateShelf(shelfkey).length === 0 ?
            (<div>no books on this shelf</div>)
            :
            (<div className="bookshelf-books">
                <ol className="books-grid">
                  <li>
                    {updateShelf(shelf.key).map(book => (
                      <Books
                        book={book}
                        books={books}
                        key={book.id}
                        onupdateShelf={this.UpdateShelf}
                      />
                    ))}
                  </li>
                </ol>
            </div>
            )
          }

        </div>
      ))}
      <Link to="/search" className="open-search">Add a book</Link>
    </div>
  </div>

    )
  }
}
import React,{Component}来自“React”
从“/BooksAPI”导入*作为BooksAPI
从“道具类型”导入道具类型
从“./Books.js”导入书籍
从“../icons/logo.svg”导入徽标
从“react router dom”导入{Link}
从“/changeself.js”导入changeself
常数托架=[
{key:'currentlyReading',
名称:'当前正在读取'},
{键:'wantToRead',
名称:'想要阅读'},
{键:'读取',
名称:'读取'}
]
导出默认类Bookshelf扩展组件{
静态类型={
书籍:PropTypes.object.isRequired,
书籍:需要PropTypes.array.isRequired,
updateSelf:PropTypes.func.isRequired
}
render(){
const{book,books,shelfkey}=this.props;
返回(
反应书架应用程序
我的书架
{shelfs.map(shelf=>(
{shelf.name}
{updateself(shelfkey).length==0?
(这个架子上没有书)
:
(
  • {updateself(shelf.key).map(book=>( ))}
  • ) } ))} 添加一本书 ) } }
    changeself.js

    import React, { Component } from 'react'
    import * as BooksAPI from './BooksAPI'
    import PropTypes from 'prop-types'
    import Books from './Books.js'
    
    export default class ChangeShelf extends Component {
    
      static propTypes = {
        book: PropTypes.object.isRequired,
        books: PropTypes.array.isRequired,
        onChangeShelf: PropTypes.func.isRequired
    }
    
    updateShelf = (book, newShelf) => {
      this.setState(previousState => {
        const newBooks = previousState.books.filter((b) => b.id !== 
    book.id)
        newBooks.push({ book, newShelf })
        return { books: newBooks }
      })
      BooksAPI.update(book, newShelf)
    }
    moveBook = (shelf) => {
      const { books } = this.props
      return books.filter(book => book.shelf === shelf)
    }
    
    render() {
      const { book, books, updateShelf } = this.props
    
        return (
          <div className="book-shelf-changer">
            <select onChange={(event) => updateShelf(book, 
    event.target.value)}>
              <option value="move" disabled>Move to...</option>
              <option value="Currently Reading">Currently Reading</option>
              <option value="Want To Read">Want to Read</option>
              <option value="Read">Read</option>
              <option value="none">None</option>
            </select>
          </div>
        )
      }
    }
    
    import React,{Component}来自“React”
    从“/BooksAPI”导入*作为BooksAPI
    从“道具类型”导入道具类型
    从“./Books.js”导入书籍
    导出默认类ChangeShelf扩展组件{
    静态类型={
    书籍:PropTypes.object.isRequired,
    书籍:需要PropTypes.array.isRequired,
    onChangeShelf:PropTypes.func.isRequired
    }
    UpdateSelf=(书籍、新闻工具)=>{
    this.setState(previousState=>{
    const newBooks=previousState.books.filter((b)=>b.id!==
    图书编号)
    newBooks.push({book,newShelf})
    返回{books:newBooks}
    })
    BooksAPI.update(书籍、新闻书架)
    }
    moveBook=(书架)=>{
    const{books}=this.props
    返回books.filter(book=>book.shelf===shelf)
    }
    render(){
    const{book,books,updateself}=this.props
    返回(
    更新自我(书,
    event.target.value)}>
    搬到。。。
    正在阅读
    想读书吗
    阅读
    没有一个
    )
    }
    }
    
    我会尽力解释;)

    组件
    App

    • 加载书籍并以状态保存数据

    • 渲染使用导入的组件

    • Bookshelf获取
      this.state.books
      as
      books
      prop和不存在的(应用程序中)处理程序/方法
      this.updateself
      as
      onUpdateShelf
      prop

    Bookshelf
    中,您可以通过
    this.props.books
    this.props.onUpdateShelf
    使用它们。这是通过道具传递处理程序。它允许从子对象调用父对象中的方法。它可以被深入地传递/使用。称为方法,异步进程通常以新状态(setState)结束,这将强制重新渲染(更新传递给childs的道具)

    为了简单起见,
    const{book,books,shelfkey}=this.props
    (在渲染中)这些道具可由本地标识符
    book
    (而不是
    this.props.book
    )、
    books
    shelfkey
    使用

    问题:

    • 未通过
      书籍

    • shelfkey
      通过

    • 缺少由
      propTypes
      根据需要定义的
      book
      updateself
      (我们有
      onUpdateShelf
      ,但传递了缺少的方法,未定义)

    • updateself
      未定义,未通过(应为
      this.props.updateself
      ),未在本地定义(应为
      this.updateself

    • updateself
      changeself
      中作为事件处理程序使用(预期)作为fn返回数组


    您可以将
    updateself
    方法从
    changeself
    移动到
    App
    ,并将其作为道具传递到Bookshelf,在需要时进行搜索和更深入的操作。

    您的
    Bookshelf
    组件中没有任何
    updateself
    方法。此外,您正在导入
    changeself
    ,但未使用它。如果你仍然对道具和状态的工作方式感到不舒服,那么就不要使用像这里这样复杂的应用程序。只要去看官方文件,先研究一下就可以了。。书架组件中有UpdateSelf方法。。。?updateself=(book,newShelf)=>{this.setState(previousState=>{const newBooks=previousState.books.filter((b)=>b.id!==book.id)newBooks.push({book,newShelf})返回{books:newBooks}})BooksAPI.update(book,newShelf)moveBook=(shelf)=>{const{books}=this.props返回图书.filter(book=>book.shelf==shelf)}render(){…….updateself(book,它在
    ChangeShelf
    组件中,而不是
    Bookshelf
    组件中。我在这里缺少什么吗?你不能从另一个组件中使用类似的方法。你可以将这些方法作为道具传递给你的子组件,并可以在那里作为道具使用。导入组件不会在主组件中提供任何方法,如
    Bookshelf
    。这就是我建议学习基础知识的原因。无意冒犯:)不客气。这肯定会有助于理解基础知识。这有助于我从中了解更多的道理,谢谢!