- Objective:
- Breadcrumb:
# 概念阐释
## 语义
在 React 中,使用 API 调用要在`useEffect()`中进行。
## 语法
# 实例
## 例1
```jsx
import React, { useState, useEffect } from 'react';
import { get } from './mockBackend/fetch';
export default function Forecast() {
const [data, setData] = useState(null); //用于存储天气数据
const [notes, setNotes] = useState({}); //用于存储注释对象
const [forecastType, setForecastType] = useState('/daily'); //用于存储天气展示的类型,每天或者每小时
useEffect(() => {
alert('Requested data from server...');
get(forecastType).then((response) => {
alert('Response: ' + JSON.stringify(response,'',2));//将 response 对象转换为 json 数据,空字符串代表不进行任何过滤,2 代表 json 字符串每个级别的缩进使用的空格数
setData(response.data);//response 获得的数据
});
}, [forecastType]);//只有forecastType发生状态变化时渲染
// 处理注释部分的改变,当有新的值被输入时,更新注释的状态,以前的注释 prev 和新的注释
const handleChange = (itemId) => ({ target }) =>
setNotes((prev) => ({
...prev,
[itemId]: target.value
}));
//如果 data 为 null不存在值,则显示 loading
if (!data) {
return <p>Loading...</p>;
}
return (
<div className='App'>
<h1>My Weather Planner</h1>
<div>
<button onClick={() => setForecastType('/daily')}>5-day</button>
<button onClick={() => setForecastType('/hourly')}>Today</button>
</div>
<table>
<thead>
<tr>
<th>Summary</th>
<th>Avg Temp</th>
<th>Precip</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
// 获取 fetch 到的 json 数据
{data.map((item) => {
return (
<tr key={item.id}>
<td>{item.summary}</td>
<td> {item.temp.avg}°F</td>
<td>{item.precip}%</td>
<td>
<input
value={notes[item.id] || ''} // 将输入框的值设置为 `notes` 对象中以 `item.id` 为键的值。如果该值不存在或是假值,则将输入框的值设置为空字符串。
onChange={handleChange(item.id)}
/>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}
```
获取的API 数据 `response.data`

## 例2
```jsx
import React, { useState, useEffect } from 'react';
import { get } from './mockBackend/fetch';
export default function Shop() {
const [categories, setCategories] = useState(null);
const [selectedCategory, setSelectedCategory] = useState(null);
const [items, setItems] = useState({});
useEffect(() => {
get('/categories').then((response) => {
setCategories(response.data);
});
}, []);
useEffect(() => {
if (selectedCategory && !items[selectedCategory]) {
get(`/items?category=${selectedCategory}`).then((response) => {
setItems((prev) => ({ ...prev, [selectedCategory]: response.data }));
});
}
}, [items, selectedCategory]);
if (!categories) {
return <p>Loading..</p>;
}
return (
<div className='App'>
<h1>Clothes 'n Things</h1>
<nav>
{categories.map((category) => (
<button key={category} onClick={() => setSelectedCategory(category)}>
{category}
</button>
))}
</nav>
<h2>{selectedCategory}</h2>
<ul>
{!items[selectedCategory]
? null
: items[selectedCategory].map((item) => <li key={item}>{item}</li>)}
</ul>
</div>
);
}
```
# 相关内容
- JSON 数据转换
- value 的默认写法
# 参考资料
- [Fetch Data-codecademy](https://www.codecademy.com/journeys/full-stack-engineer/paths/fscj-22-front-end-development/tracks/fscj-22-react-part-ii/modules/wdcp-22-function-components-and-hooks-a2dba9bf-fc64-4118-8656-dfdc35f9e5cc/lessons/the-effect-hook/exercises/fetch-data)
- [Rules of Hooks - codecademy](https://www.codecademy.com/journeys/full-stack-engineer/paths/fscj-22-front-end-development/tracks/fscj-22-react-part-ii/modules/wdcp-22-function-components-and-hooks-a2dba9bf-fc64-4118-8656-dfdc35f9e5cc/lessons/the-effect-hook/exercises/rules-of-hooks)