TLDR - You should not implement/call your reusable component within your data fetching request. The correct way to do so is having a container component that is responsible for fetching the data, storing it in state, and passing it down to a presentational component that is responsible for rendering the data as UI. (example below)
Initially what I was trying to do (I assumed components are converted to HTML and can be created as string - BAD PRACTICE):
fetch('http://localhost:8000/api/Books')
.then(response => {
if (!response.ok) {
throw Error('Network request failed.')
}
return response;
})
.then(data => data.json())
.then(data => {
let output = ''
for (let book of data) {
output += (
<Book id={book._id}
title={book.title}
author={book.author}
genre={book.genre}
read={book.read} />
);
}
console.log('parsed json', data);
document.getElementById('database').innerHTML = output;
}, (ex) => {
this.setState({
requestError : true
});
console.log('parsing failed', ex)
})
My question was:
How do i make this work? how do I Implement my Book component inside the GET request to render a reusable Book for every object in the database?
My solution
having <BooksContainer /> as my container component books data is stored in state and is iterated using .map to render each book object as a <Book /> component - our presentational function.
//BooksContainer.js - responsible for data fetching and storing
class BooksContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
books: [];
};
}
componentDidMount () {
fetch('http://localhost:8000/api/Books')
.then(response => {
if (!response.ok) {
throw Error('Network request failed.')
}
return response;
})
.then(data => data.json())
.then(data => {
this.setState({
books: data
});
console.log('parsed json', data);
}, (ex) => {
this.setState({
requestError : true
});
console.log('parsing failed', ex)
})
}
render () {
return (
<div className="books-container">
<ul className="books-list">
{this.state.books.map(book => <Book {...book} />}
</ul>
</div>
)
}
//Book.js - responsible for presenting each book's data
const Book = (props) => (
<li>
<span className="title">{this.props.title}</span>
<span className="author">Author: {this.props.author</span>
<span className="genre">Genre: {this.props.genre}</span>
<span className="read">Read: {this.props.read ? "Yes" : "No"}</span>
</li>
)