小程序获取数据库api
与componentdidmount
(Counterpart to componentdidmount
)
There are many times where we want to fetch a bunch of data when the component is mounted in React. If you are familiar with class components in React, you know that we can use componentdidmount
. With functional components, the counterpart is useEffect
. And we can use useState
to handle the data fetched from the database or API.
很多时候,当组件被安装在React中时,我们想获取一堆数据。 如果您熟悉React中的类组件,那么您知道我们可以使用componentdidmount
。 对于功能组件,对应的是useEffect
。 我们可以使用useState
来处理从数据库或API提取的数据。
例 (Example)
For example, I want to display a lot of neighborhood restaurants data that are just fetched from the database on the homepage.
例如,我要显示很多刚从主页上的数据库中获取的附近餐馆数据。
If we do it the normal way like this:
如果我们按以下常规方式进行操作:
const homepage = () => {
let restaurants = fetchData()return(
renderRestaurants(restaurants)
)
}
when our component wants to use restaurants
value, since the fetch process might take long, so we won’t see the restaurants data displayed as we expect.
当我们的组件要使用restaurants
价值时,由于获取过程可能会花费很长时间,因此我们不会看到显示的餐厅数据符合我们的预期。
But we can’t use async/await
in a functional component. We would get an error normally looks like this because React doesn’t take Promise
as a component(because after you put a async
, React would see it as a Promise
):
但是我们不能在功能组件中使用async/await
。 我们通常会收到这样的错误,因为React不会将Promise
当作组件(因为在放置async
,React会将其视为Promise
):
Objects are not valid as a React child (found: [object Promise]).
Then what can we do?
那我们该怎么办?
解 (Solution)
useEffect(() => {
fetchData()
})
As you can see, useEffect
takes a function as the first parameter. It will automatically be fired after each render. It will be fired before other things so we can make sure the data is there when we want to display it.
如您所见, useEffect
将函数作为第一个参数。 每次渲染后都会自动将其触发。 它将在其他事物之前触发,因此我们可以确保要显示的数据在那里。
我们如何处理获取的数据? (How do we handle the data that we fetched?)
A: We can use useState
to handle it:
答:我们可以使用useState
来处理它:
const [restaurants, setRestaurants] = useState([])useEffect(() => {
let data = fetchData();
setRestaurants(data)
})
In this example, we set a restaurants
state for the component and also set the default value as an array. The setRestaurants
is the method to change that restaurants
value.
在此示例中,我们为组件设置了一个restaurants
状态,并且还将默认值设置为一个数组。 setRestaurants
是更改restaurants
价值的方法。
Therefore, in the useEffect
, we invoke fetchData()
to get the data from db or API, and then we should get a series of restaurants data in the neighborhood. Then we can pass that data to setRestaurants
so restaurants
will be updated for our future use in the document.
因此,在useEffect
,我们调用fetchData()
从db或API中获取数据,然后应该在附近获取一系列餐厅数据。 然后,我们可以将该数据传递给setRestaurants
以便将restaurants
更新以供将来在文档中使用。
异步部分呢? (What about the asynchronous part?)
To be clear, if you try to do this:
要明确的是,如果您尝试这样做:
useEffect( async() => {
let data = await fetchData();
setRestaurants(data)
})
You would get an error too. You can call the asynchronous function like so:
您也会得到一个错误。 您可以像这样调用异步函数:
useEffect(() => {
getRestaurants = async() => {
await fetchData()
setRestaurants(data)
}
getRestaurants();
})
The solution is that we wrap the asynchronous part in another function and then call it later.
解决方案是,将异步部分包装到另一个函数中,然后再调用它。
如果我们希望仅在更改值时将其触发该怎么办? (What if we want it only to be fired when a value is changed?)
A: If we pass a second argument to useEffect
, codes would look like:
答:如果我们将第二个参数传递给useEffect
,则代码将如下所示:
useEffect(() => {
getRestaurants = async() => {
await fetchData()
setRestaurants(data)
}
getRestaurants();
, [restaurants]
})
What does the second argument mean? Basically it tells the component to compare previous restaurants
with the currentrestaurants
value, if there is no difference, then the effect would be skipped.
第二个参数是什么意思? 基本上,它告诉组件将以前的restaurants
与当前restaurants
值进行比较,如果没有差异,则将跳过效果。
Thanks for reading!
谢谢阅读!
小程序获取数据库api