[英]“cannot read property 'map' of undefined” when state is updated ReactJS
I´m having an issue when udating the state, i´m sure the data i´m getting from the API is right cause i check it with the console.log(), and for some reason the error only happens for searchs with more than 1 letter. 我在查询状态时遇到问题,我确定我从API获取的数据是正确的,因为我使用console.log()进行了检查,并且由于某些原因,该错误仅发生在具有更多内容的搜索中超过1个字母。 I tried solving this using conditionals before the map, mobx and just the normal setState.
我尝试在地图,mobx和普通setState之前使用条件句解决此问题。
This is the code using mobx: 这是使用mobx的代码:
const BookSearch = observer(class BookSearch extends Component{
state = observable({
query: '',
books: []
})
searchBooks = (query) =>{
console.log(query.target.value)
this.state.query = query.target.value
BooksAPI.search(query.target.value, 20).then((books) =>{
console.log(books)
this.state.books = books;
console.log(this.state.books)
})
console.log(this.state.books)
}
render(){
const { query } = this.state;
const bookSearch = this.state.books.map((book) =>
<li key={book.id}>
<div 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={(event) => this.props.bookChange(book, event.target.value)}>
<option>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.map((author) =>
<span key={ author + book.title } >{ author }</span>
)}</div>
</div>
</li>
) ;
return(
<div>
<div className="search-books">
<div className="search-books-bar">
<Link className="close-search" to='/'>Close</Link>
<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"
onChange={ this.searchBooks}
/>
</div>
</div>
<div className="search-books-results">
<div className="bookshelf">
<h2 className="bookshelf-title">{ this.state.query }</h2>
<div className="bookshelf-books">
<ol className="books-grid">
{ bookSearch }
</ol>
</div>
</div>
</div>
</div>
</div>
)
}
})
and this is the searchBooks function without mobx: 这是没有mobx的searchBooks函数:
searchBooks = (query) =>{
this.setState({ query: query.trim() });
BooksAPI.search(query, 20).then((books) =>{
this.setState({ books: books });
})
console.log(this.state.books)
}
I have no idea how to solve this issue. 我不知道如何解决这个问题。 thanks for the help.
谢谢您的帮助。
From what I can gather from your code snippet your this.state.books
is undefined that's because 从我的代码片段中可以
this.state.books
是未定义的,这是因为
while setting books in your state you are doing it wrongly it should be 在您的状态下放置书籍时,您做错了
this.setState({books: books})
and immediately after that console.log()
wont always give you the updated results. 并且在那之后
console.log()
不会总是给您更新的结果。
so now your searchBooks
will be: 所以现在您的
searchBooks
将是:
searchBooks = (query) =>{
console.log(query.target.value)
this.state.query = query.target.value
BooksAPI.search(query.target.value, 20).then((books) =>{
console.log(books)
this.setState({books});
// reactive way you can also do this.setState({books: books})
})
}
and if sometime this is empty you can assign it to empty array: 如果某个时间为空,则可以将其分配给空数组:
const {books = []} = this.state
const bookSearch = books.map((book) =>
<li key={book.id}>
<div 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={(event) => this.props.bookChange(book, event.target.value)}>
<option>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.map((author) =>
<span key={author + book.title} >{author}</span>
)}</div>
</div>
</li>
);
Hope this helps. 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.