我进行了一个API调用。
React似乎在没有数据的情况下构建了一个表,从而抛出了的错误
Uncaught TypeError: Cannot read property 'map' of undefined
以下是我正在做的
useEffect()
相当简单的
const [data, setData] = useState();
const [isBusy, setBusy] = useState()
useEffect(() => {
setBusy(true);
async function fetchData() {
const url = `${
process.env.REACT_APP_API_BASE
}/api/v1/endpoint/`;
axios.get(url).then((response: any) => {
setBusy(false);
setData(response.data.results)
console.log(response.data.results);
});
}
fetchData();
}, [])
然后,我尝试使用上面API调用中的数据来呈现一个表(当它可用时(
<div className="col-md-12 mt-5">
{isBusy ? (
<Loader />
) : (
<table className="table table-hover">
<thead>
<tr>
<th scope="col">Pharmacy User Full Name</th>
<th scope="col">Tests This Month</th>
<th scope="col">Tests This Week</th>
<th scope="col">Last Test Date</th>
</tr>
</thead>
<tbody>
{data.map((item: any, index: any) => {
return (<tr>
<th scope="row" key={index}>{item.name}</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
)
})}
</tbody>
</table>
)}
</div>
以上内容对我来说已经足够直观了。所以不确定我需要做什么。谢谢。
您应该在useState
初始值中将isBusy
设置为true
// initial value
const [isBusy, setBusy] = useState(true)
并在data.map
之前检查data
// checking data
{data && data.map((item: any, index: any) => {
return (<tr>
<th scope="row" key={index}>{item.name}</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
)
})}
useEffect
只会在组件尝试渲染后(为时已晚(将isBusy
设置为true
。请记住,useEffect
仅在浏览器完成绘制后运行。因此isBusy
的第一个断言是undefined
,其评估为false
将true
定义为isBusy
的初始状态
const [isBusy, setBusy] = useState(true)
或者检查是否存在data
而不是isBusy
您的setBusy(true);
发生在useEffect
内部。useEffect
将在第一次渲染后执行,因此为时已晚。
我建议通过useState
:的参数将isBusy
默认设置为true
const [isBusy, setBusy] = useState(true);
然后您就不需要再在useEffect
中将其设置为true了。
您可以完全删除isBusy
状态变量,因为它只是复制数据。除非你后来决定做一些花哨的事情,比如"加载更多数据",否则我认为这只会使事情变得复杂。
<div className="col-md-12 mt-5">
{!data? (
<Loader />
) : (
<table className="table table-hover">
<thead>
<tr>
<th scope="col">Pharmacy User Full Name</th>
<th scope="col">Tests This Month</th>
<th scope="col">Tests This Week</th>
<th scope="col">Last Test Date</th>
</tr>
</thead>
<tbody>
{data.map((item: any, index: any) => {
return (<tr>
<th scope="row" key={index}>{item.name}</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
)
})}
</tbody>
</table>
)}
</div>
在上文中,如果没有数据!data
,则它将显示加载器。一旦数据被填充,它将使用加载的数据来渲染表。
希望这能有所帮助。