reactjs - 反应应用程序状态未更新
问题描述
我正在创建一个基本的 React 应用程序来将书籍放在某些书架上,并尝试创建在书架之间移动书籍的功能。
我遇到的问题是,当我从书籍对象下拉列表中选择新的目标书架时,onUpdateShelf
in 中的方法ListBooks.js
似乎没有启动更新和后续状态更改。
我是 React 的新手,我的理解是调用setState
函数updateShelf
应该触发更新对象的重新渲染。
那么我的问题是,我的实施是否错误,在哪里?
App.js
import React, { Component } from 'react'
import ListBooks from './ListBooks'
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) => {
console.log(book)
console.log(shelf)
this.books.forEach(b => {
if(b.id === book.id && b.shelf !== book.shelf ) {
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}
/>
)} />
</div>
)
}
}
export default BooksApp
和我的ListBooks.js
import React, { Component } from 'react';
import PropTypes from 'prop-types'
import './App.css'
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
}
state = {
showSearchPage: false,
query: ''
}
render() {
const { books, onUpdateShelf } = this.props
function getBooksForShelf(shelfKey) {
return books.filter(book => book.shelf === shelfKey);
}
console.log(books);
return(
<div className="app">
{this.state.showSearchPage ? (
<div className="search-books">
<div className="search-books-bar">
<a className="close-search" onClick={() => this.setState({ showSearchPage: false })}>Close</a>
<div className="search-books-input-wrapper">
{/*
NOTES: The search from BooksAPI is limited to a particular set of search terms.
You can find these search terms here:
https://github.com/udacity/reactnd-project-myreads-starter/blob/master/SEARCH_TERMS.md
However, remember that the BooksAPI.search method DOES search by title or author. So, don't worry if
you don't find a specific author or title. Every search is limited by search terms.
*/}
<input type="text" placeholder="Search by title or author"/>
</div>
</div>
<div className="search-books-results">
<ol className="books-grid"></ol>
</div>
</div>
) : (
<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) => (
<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>
<option value="none" disabled>Move to...</option>
<option value="currentlyReading" onClick={() => onUpdateShelf(book, 'currentlyReading')} >Currently Reading</option>
<option value="wantToRead" onClick={() => onUpdateShelf(book, 'wantToRead')} >Want to Read</option>
<option value="read" onClick={() => onUpdateShelf(book, 'read')} >Read</option>
<option value="none" onClick={() => onUpdateShelf(book, '')} >None</option>
</select>
</div>
</div>
<div className="book-title">{book.title}</div>
<div className="book-authors">{book.author}</div>
</div>
))}
</li>
</ol>
</div>
</div>
)) }
</div>
</div>
<div className="open-search">
<a onClick={() => this.setState({ showSearchPage: true })}>Add a book</a>
</div>
</div>
)}
</div>
)
}
}
export default ListBooks
解决方案
当您updateShelf
传递给您的组件ListBooks
时,您会丢失this
inside的值updateShelf
,结果this.books
将是未定义的。
您可以通过在以下构造函数中执行此操作来解决此问题BooksApp
:
this.updateShelf = this.updateShelf.bind(this)
或者通过使用箭头函数:
<Route exact path='/' render={() => (
<ListBooks
books={this.state.books}
onUpdateShelf={() => { this.updateShelf()} }
/>
)} />
编辑
您已经在使用arrow functions
inside BooksApp
,所以我之前所说的没有必要。
但是,您仍然应该使用this.state.books
而不是this.books
inside updateShelf
。
推荐阅读
- google-apps-script - 如何处理来自 Google 脚本库中 HTML 文件的回调
- swift - 我正在尝试将字符串日期转换为日期,但即使在设置 dateFormat 后它仍然返回 nil
- flutter - 如何对颤振进行响应性测试
- sql - 从每周计算月收入
- python - 如何在机器人框架中生成随机电子邮件?
- r - R中的插入符号包:当我重复测量时,如何将数据分成75%的测试和25%的训练?
- java - 我的 api REST 调用 OSB oracle 服务总线有什么问题,jdeveloper
- javascript - 如何按顺序查询列表的内容?
- jquery - 使用jQuery从父节点中的元素中删除类
- c# - 使用 XMLUnit 将一个 XML 文档与另一个文档进行比较?