Hi I am pretty new to React and having really hard time wrapping my head around this whole state management and passing data through state and props. I do understand that the standard react way is to pass down data in a unidirectional way- from parent to child, which I have done so for all other components. But I have this component called Book, which changes its 'shelf' state, based on user selection form 'read, wantToRead, currentlyReading, and none'. And in my BookList component which renders Book component, but it needs to be able to read Book's shelf state and render the correct books under sections called 'read, wantToRead, currentlyReading, and none'. And since in this case, Book component is being rendered from BookList component and BookList being the parent, i really cannot understand how to enable BookList to access Book's state? BookList component:
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import Book from './Book'
class BookList extends Component {
render(){
const { books, shelf } = this.props
return (
<div className="list-books">
<div className="list-books-content">
<div className="list-books-title">
<h1>MyReads</h1>
</div>
<div className="bookshelf">
<h2 className="bookshelf-title">None</h2>
{books.map((book)=> {
console.log(book)
if (shelf === ''){
return <div className="bookshelf-books">
{/* <BookStateless book= {book} /> */}
<Book book = {book} />
{/* <BookStateless book= {book} /> */}
</div>
}
})}
</div>
<div className="bookshelf">
<h2 className="bookshelf-title">Currently Reading</h2>
{books.map((book)=> {
if (shelf === 'currentlyReading'){
return <div className="bookshelf-books">
{/* <BookStateless book= {book} /> */}
<Book book = {book} />
</div>
}
// console.log(this.book.title, this.book.state)
})}
</div>
<div className="bookshelf">
<h2 className="bookshelf-title">Want to Read</h2>
{books.map((book)=> {
if (shelf === 'wantToRead'){
return <div className="bookshelf-books">
{/* <BookStateless book= {book} /> */}
<Book book = {book} />
{/* <BookStateless book= {book} /> */}
</div>
}
// console.log(this.book.title, this.book.state)
})}
</div>
<div className="bookshelf">
<h2 className="bookshelf-title">Read</h2>
{books.map((book)=> {
if (shelf === 'read'){
console.log(shelf)
return <div className="bookshelf-books">
{/* <BookStateless book= {book} /> */}
<Book book = {book} />
</div>
}
// console.log(this.book.title, this.book.state)
})}
</div>
</div>
<div className="open-search">
<Link to="/search">Add a book</Link>
</div>
</div>
)
}
}
export default BookList
Book component:
import React, { Component } from 'react'
// import * as BooksAPI from './BooksAPI'
import Select from 'react-select'
import 'react-select/dist/react-select.css'
class Book extends Component {
state={
// state can be read, none, want to read, or currently reading
shelf: ''
}
handleChange(e){
this.setState({ shelf: e['value'] })
console.log("this?", this)
}
render(){
const { book } = this.props
const { shelf } = this.state
console.log("book", book.state)
const options = [
{ value: 'currentlyReading', label: 'currentlyReading'},
{ value: 'wantToRead', label: 'wantToRead'},
{ value: 'read', label: 'read'},
{ value: 'none', label: 'none'}
]
return (
<li key={book.id}>
<div className="book">
<div className="book-top">
<div className="book-cover" style={{ width: 128, height: 188, backgroundImage: `url("${book.imageLinks.thumbnail}")` }}></div>
<div className="book-shelf-changer">
<Select
value=""
options={options}
onChange={(e)=>this.handleChange(e)}
/>
</div>
</div>
<div className="book-title">{book.title}</div>
<div className="book-authors">{book.authors}</div>
</div>
</li>
)
}
}
export default Book
in my app.js i have:
import React from 'react'
import * as BooksAPI from './BooksAPI'
import './App.css'
import Search from './Search'
import BookList from './BookList'
import Book from './Book'
import { Route } from 'react-router-dom'
class BooksApp extends React.Component {
state = {
books : []
}
componentDidMount(){
BooksAPI.getAll().then((books)=> {
this.setState({ books: books })
// console.log("bookstest",this)
})
}
render() {
return (
<div className="App">
<Route exact path="/" render={()=>(
<Book books={this.state.books} />
)} />
<Route path="/search" render={()=>(
<Search books={this.state.books} />
)} />
<Route path="/BookList" render={()=>(
<BookList books={this.state.books} />
)} />
</div>
)
}
}
export default BooksApp
Right now, when i open the booklist component in browser, i get no books because it's not picking up the state in any of the if statements here:
if (shelf === 'currentlyReading'){
return <div className="bookshelf-books">
}
Thank you so much in advance for reading through and, any help would be much appreciated! Thank you!