在 React 类中获取数据并更新状态
介绍
你是否需要在 React 组件中渲染来自服务器的数据?我猜是的,你曾经需要过。但如何实现这一点并不总是很清楚。你可能会问:
- 这是否必须在用户交互之后发生?
- 我需要 Redux/Mobx 吗?
- 是否有适合这种用例的特定 React 库?
我想解释如何使用从服务器获取的数据来更新类组件中的组件状态,并希望消除有关该主题的任何困惑。
假设我们有一个关于哈利波特的应用程序。您可以阅读有关角色、他们的背景故事、每本书的详细信息等。此应用程序中的一个组件列出了哈利波特系列中的每一本书。书籍详细信息需要来自 Rest API,因此让我们看看如何在 React 类组件中执行此操作。
渲染时的状态
我们要解决的问题是:
当组件加载时,我需要它向我的 REST API 创建一个请求来提取一些数据。
那么问题是,“我在组件中的哪里发出这个请求?”答案是在生命周期方法之一中。
类组件生命周期方法
尽管 React 组件中有几种生命周期方法,但我们将重点关注的获取请求方法是componentDidMount()和componentWillUnmount()。
import React from 'react';
class ProductList extends React.Component {
componentDidMount() {
// make fetch request
}
componentWillUnmount() {
// make fetch request
}
render() {
return (
<ul>
<li />
</ul>
)
}
}
组件将卸载()
当需要在组件卸载时执行操作时,可以使用 componentWillUnmount() 方法。常见场景包括取消订阅实时监听器或跟踪卸载事件。在本指南的其余示例中,我们不需要 componentWillUnmount ( )方法,因此我们将使用componentDidMount()方法。
组件挂载()
根据 React 文档:
componentDidMount() 在组件被挂载(插入到树中)后立即被调用。
componentDidMount 方法是向服务器请求数据的最佳位置,因为即使设置状态会导致第二次渲染,但它发生在浏览器更新屏幕之前。用户不会看到中间状态。
那么我该如何更新状态?
我们要做的是获取《哈利波特》书籍列表,并将它们显示在列表中。
我首先想在我们的初始状态设置一个书籍对象:
class BookList extends React.Component {
state = {
books: []
}
}
我们将把我们的书籍呈现为如下的无序列表:
- 哈利·波特与魔法石
- 哈利·波特与密室
- 哈利·波特与阿兹卡班的囚徒
- ETC
class BookList extends React.Component {
state = {
books: []
}
render() {
return (
<ul>
{this.state.books.map((book) => (
<li key={book.id}>{book.name}</li>
))}
</ul>
)
}
}
为了用书籍填充我们的状态,我们需要使用 componentDidMount() 生命周期方法。
..
componentDidMount() {
fetch('https://some-api.com/harry-potter')
.then((response) => response.json())
.then(booksList => {
this.setState({ books: booksList });
});
}
..
刚才到底发生了什么?
这里发生的事情是:
- 该组件将开始插入到 DOM 中。
- 初始渲染发生(书籍数组为空)。
- 然后调用componentDidMount()
- 一旦该请求成功完成,就会调用setState()并且books属性将使用所有哈利波特书籍进行更新。
调用setState()会触发新的渲染,并且每本书现在都会显示在无序列表中。
以下是完整的示例:
class BookList extends React.Component {
state = {
books: []
}
componentDidMount() {
fetch('https://some-api.com/harry-potter')
.then((response) => response.json())
.then(booksList => {
this.setState({ books: booksList });
});
}
render() {
return (
<ul>
{this.state.books.map((book) => (
<li key={book.id}>{book.name}</li>
))}
</ul>
)
}
}
根据用户事件更新状态
那么当我们想要在组件初始加载后发出异步请求时该怎么办?如果我想在用户单击按钮时获取书籍怎么办?我们可以将获取调用移出 componentDidMount() 方法,并在新方法中调用我们的 API,我们将该方法定义为fetchBooks():
class BookList extends React.Component {
state = {
books: []
}
fetchBooks = () => {
fetch('https://some-api.com/harry-potter')
.then((response) => response.json())
.then(booksList => {
this.setState({ books: booksList });
});
}
render() {
return (
<>
<button onClick={this.fetchBooks}>Load Books</button>
{this.books.length > 0 && (
<ul>
{this.state.books.map((book) => (
<li key={book.id}>{book.name}</li>
))}
</ul>
)}
</>
)
}
}
我们在这里所做的就是添加一个按钮,当单击该按钮时,它会发出与之前在componentDidMount()方法中相同的获取请求。我还在图书列表的渲染周围添加了一个条件,即仅当图书数量超过零本时才渲染列表。
结论
在 React 应用程序中,从服务器获取和渲染数据非常常见。React.Component类为我们提供了一个生命周期方法,使此操作变得容易,我建议使用 componentDidMount ()来发出组件加载时发生的任何异步请求。
我们将在另一个指南中讨论如何在功能组件中执行相同的任务。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~