我正在创建一个React应用程序,需要更新状态并根据用户从Select Box中选择的选项调用API。由于我无法在<option></option>
代码中放置函数调用,因此我需要在调用value
时从选项标记中检索onChange
。
我已在应用状态中创建了selectValue
值以进行更新,并尝试在以下帖子中模拟解决方案。
Using Props And State To Pass Value Of Select Box To Child Component React.JS
但是,我遇到的问题是我不知道如何从所选选项中选择并传递value
。
我通过在onHandleSelectValue
文件中对ListBooks.js
传递的值进行硬编码来测试它。当我这样做时,状态会按预期更新。
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: [],
selectValue: 'wantToRead'
}
componentDidMount() {
BooksAPI.getAll()
.then((books) => {
this.setState(() => ({
books
}))
})
}
updateShelf = (book) => {
const shelf = this.state.selectValue
this.state.books.forEach(b => {
if(b.id === book.id) {
console.log('Shelf: ' + this.state.selectValue)
b.shelf = shelf
this.setState((currentState) => ({
books: currentState.books
}))
}
});
BooksAPI.update(book, shelf)
}
handleSelectValue(option) {
console.log('handleSelectValue: ' + option)
this.setState((currentState) => ({
selectValue: option
}))
console.log('handleSelectValue + selectValue: ' + option)
}
render() {
return (
<div>
<Route exact path='/' render={() => (
<ListBooks
books={this.state.books}
onUpdateShelf={this.updateShelf}
onHandleSelectValue={this.handleSelectValue.bind(this)}
/>
)} />
</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'
},
// {
// key: '',
// name: 'None'
// }
];
class ListBooks extends Component {
static propTypes = {
books: PropTypes.array.isRequired
}
state = {
showSearchPage: false,
query: ''
}
render() {
const { books, onUpdateShelf, onHandleSelectValue } = 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 onChange={() => onUpdateShelf(book, onHandleSelectValue('read'))}>
<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.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
答案 0 :(得分:2)
所以使用@Praveen Kumar提供的建议。
我删除了额外的处理程序,只是更改了以下行,将所选选项中的value
作为参数传递。
<select onChange={(e) => onUpdateShelf(book, e.target.value)}>