调用API填充Material UI List时列表为空的问题求助
解决React中axios异步请求导致数据数组为空的问题
问题根源
- 普通变量无法触发组件重渲染:你用
let resultArray = []这种普通变量存储请求结果,React无法监测它的变化。当axios异步请求完成后,即使数组内容更新,组件也不会重新渲染,所以始终显示空数组。 - concat方法的误用:
concat会返回一个新数组,不会修改原数组resultArray,所以你的赋值操作实际上没生效。 - API请求未受控:直接在组件顶层发起axios请求,会导致组件每次渲染都重复调用接口,既浪费资源又可能引发不必要的问题。
修正后的代码
import { Box, List, ListItemButton, ListItemText } from "@mui/material" import { useEffect, useState } from "react"; import axios from "axios"; function RequestApproval() { // 用useState声明状态变量,让React能追踪数据变化 const [resultArray, setResultArray] = useState([]); // 用useEffect包裹API请求,确保只在组件挂载时执行一次 useEffect(() => { const fetchUsers = async () => { try { const response = await axios.get("http://localhost:3001/all-user-addresses"); // 直接用setState更新状态,触发组件重渲染 setResultArray(response.data.result); } catch (error) { console.error("获取用户数据失败:", error); } }; fetchUsers(); }, []); // 空依赖数组表示仅在组件挂载时执行 // 根据状态变量生成列表项,数据更新后会自动重新渲染 const listItems = resultArray.map((item) => ( <ListItemButton key={item.public_address} component="a" onClick={() => alert("Clicked")}> <ListItemText primary={`${item.first_name} ${item.last_name}`} /> </ListItemButton> )); return ( <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}> <Box style={{ borderRadius: '16px', backgroundColor: '#6ea6be' }}> <List sx={{ width: '600px', maxWidth: '1000px' }}> {listItems} </List> </Box> </div> ); } export default RequestApproval;
关键修改说明
- 使用
useState声明resultArray状态变量,替代普通变量,这样数据更新时React会自动触发组件重渲染。 - 用
useEffect包裹API请求,通过空依赖数组[]确保请求只在组件挂载时执行一次,避免重复请求。 - 改用
async/await语法处理异步请求,代码更易读;请求成功后直接用setResultArray更新状态。 - 给每个
ListItemButton添加key属性(用唯一的public_address),符合React列表渲染的最佳实践,避免警告。 - 合并
first_name和last_name显示,让列表项信息更完整。
内容的提问来源于stack exchange,提问作者Khandkar Islam
相关产品推荐
相关产品推荐

