[英]Fetch GET request with Reactjs - how do i implement a reusable component within my request to render my data?
TLDR - You should not implement/call your reusable component within your data fetching request. TLDR - 您不应在数据获取请求中实现/调用可重用组件。 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.正确的做法是让容器组件负责获取数据,将其存储在state
,并将其传递给负责将数据呈现为 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 ):最初我试图做的是(我假设组件被转换为 HTML 并且可以创建为字符串 - 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 ?如何在 GET 请求中实现我的 Book 组件,以便为数据库中的每个对象呈现可重用的 Book ?
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 />
作为我的容器组件书籍数据存储在 state 中,并使用.map
进行迭代以将每个书籍对象呈现为<Book />
组件 - 我们的展示功能。
//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>
)
You should store the result of the api inside the state and render the <Book />
inside the render
function.您应该将 api 的结果存储在 state 中,并在render
函数中呈现<Book />
。
Btw it would be better to separate your components:顺便说一句,最好将您的组件分开:
You can even go further by using redux
for handling a global state, and redux-saga
for handling the side effects (api calls)您甚至可以通过使用redux
处理全局状态和使用redux-saga
处理副作用(api 调用)来更进一步
EDIT编辑
Here is a small example.这是一个小例子。
The presentational component:演示组件:
const BookListing = ({ books }) => (
<ul>
{books.map(book => <li key={book.id}>{book.title}</li>)}
</ul>
);
The container component:容器组件:
class Books extends Component {
constructor(props) {
super(props);
this.state = {books: []};
}
componentDidMount() {
fetch('http://localhost:8000/api/Books')
.then(data => data.json())
.then((data) => { this.setState({ books: data }) });
}
render() {
return <BookListing books={this.state.books} />;
}
}
1) Create a container component where you can do your AJAX request and then save the result in your local state, say books
in the render
method. 1)创建一个容器组件,您可以在其中执行 AJAX 请求,然后将结果保存在您的本地状态中,例如render
方法中的books
。
2) Pass the this.state.books
into your <Book />
component where you can iterate over the array. 2) 将this.state.books
传递到您的<Book />
组件中,您可以在其中迭代数组。
3) (Optional but recommended). 3)(可选但推荐)。 You can create another component like <BookDetail />
to render individual book item您可以创建另一个组件,如<BookDetail />
来呈现单个书籍项目
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.