The following code works only with one letter searchs or less (0 letters), i don´t understand what is happening, but apparently it´s a problem in the state update.
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import * as BooksAPI from './BooksAPI';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
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>
)
}
})
I´m using mobx, but i had the same problems without it.
I’ve used two way data binding with React recently also.
Let me know if that works… That would be my best guess. I believe the problem is that you’re not binding the data with .bind(this)… Also the react docs show the value defined explicitly in the input tag.
<input
type="text"
placeholder="Search by title or author"
onChange={ this.searchBooks.bind(this)}
value={this.state.query}
/>
At this point I feel the issue is related more to MobX than React itself.
It would be nice to have a working demo so that I can help you debug it; so far this it what I would look into it:
1 - No usage of decorators
this means that the syntax for declaring observables is different ( I fear you have to bind this, but I’m not sure, refer to MobX docs on the usage without decorators.
EDIT2 - clarification on this point:
2 - React won’t re-render from direct state update like that, so if MobX observable has something wrong (point 1) we cannot rely on this.state to actually cause a re-render.
Sorry if I cannot be of more help but besides some prototyping I’ve never used MobX
EDIT:
I´m using mobx, but i had the same problems without it.
If you don’t mind I’d like to see the non-mobx version
p.s. the setState is async note was related to the console.log() that was following it, not the issue itself.
As you can see from the inspector the error is coming from MobX, specifically from observablearray.
There’s definitely something wrong in the way your mobx is interacting with the app.
Have you tried using it with decorators?
My suggestion is to make the component without MobX first and see if everything works as expected. Then integrate it with a Store library to see what/where went wrong.
Here I created a sandbox with a bare minimum working app that lets you write in a (controlled) input and search for that user in the GithubAPI.
You have a different API endpoint but the mechanism should be the same.
Hope it helps