如何从 api 迭代对象列表并将其呈现到 jsx 页面 React 功能组件
2021-03-12
1169
我尝试使用 useEffect 从 api 响应中获取数组项列表,结果我得到了一个对象列表。我想使用 Objects.key() 方法进行转换,但当我迭代它时,值不会打印在视图页面上。响应继续返回来自 api 响应的调用。
API 调用
export function getServicesById(facility_id) {
return axios
.get(`${baseURL}patients/appointments/1`)
.then((response) => {
if(response.status===200){
// console.log(response.data)
return response
}
}).catch(error => {
console.log('error', error)
return error
});
}
使用 useEffect 获取响应数据
useEffect(() => {
getServicesById()
.then((res) => {
setResponseData(res.data);
})
.catch((error) => {
console.log(error);
});
// console.log('data is', newResponseData);
}, [responseData, setResponseData]);
将对象转换为数组项
const newResponseData = Object.keys(responseData).reduce((array, key) => {
return [...array, { key: responseData[key] }];
}, []);
我正在呈现数据的 Jsx 页面
<TableBody>
{newResponseData &&
newResponseData.map((serv, index) => (
<TableRow key={index}>
<TableCell align="left" data-label="Action">
<Field
name="status"
component={renderSelectInput}
variant="outlined"
size="small"
className="fileds"
inputClass="sm-filed"
>
<MenuItem selectedValue="progress">
In progress
</MenuItem>
<MenuItem value="closed">
Closed
</MenuItem>
</Field>
</TableCell>
<TableCell data-label="Id">{serv.id}</TableCell>
<TableCell data-label="Patient name">{serv.patient_name}</TableCell>
<TableCell data-label="Test Name">{serv.test_name}</TableCell>
</TableRow>
))}
</TableBody>
2个回答
问题
您正在使用效果更新的
useEffect
依赖项:
useEffect(() => {
getServicesById()
.then((res) => {
setResponseData(res.data);
})
.catch((error) => {
console.log(error);
});
}, [responseData, setResponseData]);
responseData
由效果更新,更新后将触发另一次重新渲染,效果将再次运行。您可能只想在组件安装时获取一次数据。
我看到的另一个潜在问题是
newResponseData
数组仅包含一个
key
键的对象。
const newResponseData = Object.keys(responseData).reduce((array, key) => {
return [...array, { key: responseData[key] }];
}, []);
但在渲染中,您尝试访问
id
、
patient_name
和
test_name
属性。由于
{ key: responseData[key] } 不具备上述任何属性,因此这些属性未定义。
解决方案
删除
useEffect
依赖项,以便效果在组件安装时运行一次。由于我还认为您打算计算
responseData
中的对象值数组以将其映射到您的 UI 中,因此您可以在
之前
执行一次此操作将数据发送到状态。
useEffect(() => {
getServicesById()
.then((res) => {
const data = Object.values(res.data)
setResponseData(data);
})
.catch((error) => {
console.log(error);
});
}, []);
然后只需映射您的
responseData
状态:
<TableBody>
{responseData && responseData.map((serv, index) => (
<TableRow key={index}>
<TableCell align="left" data-label="Action">
<Field
name="status"
component={renderSelectInput}
variant="outlined"
size="small"
className="fileds"
inputClass="sm-filed"
>
<MenuItem selectedValue="progress">
In progress
</MenuItem>
<MenuItem value="closed">
Closed
</MenuItem>
</Field>
</TableCell>
<TableCell data-label="Id">{serv.id}</TableCell>
<TableCell data-label="Patient name">{serv.patient_name}</TableCell>
<TableCell data-label="Test Name">{serv.test_name}</TableCell>
</TableRow>
))}
</TableBody>
Drew Reese
2021-03-12
除了 Drew Reese 的上述回答之外,请从 useEffect 参数中删除 responseData,因为您在其中使用了 setResponseData ,并且 useEffect 会在每次状态改变时触发:
useEffect(() => {
getServicesById()
.then((res) => {
setResponseData(res.data);
})
.catch((error) => {
console.log(error);
});
}, [setResponseData]);
NeERAJ TK
2021-03-12