等待API调用数据,然后再渲染react钩子



我进行了一个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,则它将显示加载器。一旦数据被填充,它将使用加载的数据来渲染表。

希望这能有所帮助。

相关内容

  • 没有找到相关文章

最新更新