- 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` ![](https://image.harryrou.wiki/2024-01-09-CleanShot%202024-01-10%20at%2006.57.17%402x.png) ## 例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)