Uncaught (in promise) TypeError: data.map is not a function (React using axios getting data from ASP.NET API)
Uncaught (in promise) TypeError: data.map is not a function (React using axios getting data from ASP.NET API)
我使用 ASP.NET 创建了一个 API,并且我有一个网站 运行 React。我想使用 Axios 显示从 API 到 React 的获取请求检索的数据。该网站有使用两个 cookie 的身份验证方法。我可以让 Axios 从 https://jsonplaceholder.typicode.com/users 获取数据,但是当我使用相同的代码时,我会收到错误消息:Uncaught (in promise) TypeError: data.map is not a function.
我试过如上所述使用占位符,效果很好,但似乎无法从我的 API 获取数据,这让我相信问题出在 cookie 上.我还尝试了一些 Google 搜索,返回结果是我应该包含 withCredentials: true,但这并不能解决问题。
这是我 API 的函数:
public JsonResult YearlyManagersJSON(int year = 0)
{
if (year < 2000 || year > DateTime.Today.Year)
year = DateTime.Today.Year;
var startDate = new DateTime(year, 1, 1);
var endDate = new DateTime(year + 1, 1, 1);
var bonds = this.getOverviewData(ReportType.BONDS, startDate, endDate);
var bondsSum = bonds.Sum(m => m.Aggregate);
var viewData = new TopLeadManagerViewData
{
Title = String.Format("Top Managers in {0}", startDate.Year),
Currency = SiteHelper.getCurrencyToUse(),
Bonds = Enumerable.Select(bonds, m => new ManagerSummary()
{
NumberOfIssues = (int)m.Aggregate2,
TotalAmount = m.Aggregate * 1000000,
Name = m.Group.ToString(),
Share = 100.0m * m.Aggregate / bondsSum
}),
};
return this.Json(viewData, JsonRequestBehavior.AllowGet);
}
This returns a JSON,我已经使用 Postman 检查过了。然后我尝试使用 axios 访问数据。
state = {
yearlyBonds: []
}
componentDidMount() {
axios.get(
'http://localhost/Stamdata.Web/LeagueTable/YearlyManagersJSON',
{ withCredentials: true }
)
.then(res => {
const yearlyBonds = res.data;
this.setState({ yearlyBonds });
})
}
render() {
return (
// Tags removed for simplicity
<ListTable data={this.state.yearlyBonds.Bonds} />
然后将数据向下传递到组件中
function ListTable(props) {
const { classes, header, data } = props;
return(
// Tags removed for simplicity
<TableBody>
{data.map((x, i) => {
return(
<TableRow key={i}>
<TableCell scope="row">{x.Name}</TableCell>
<TableCell scope="row">{x.TotalAmount}</TableCell>
<TableCell scope="row">{x.Share}</TableCell>
<TableCell scope="row">{x.NumberOfIssues}</TableCell>
</TableRow>
)
})}
</TableBody>
所以,这个 returns 错误
"Uncaught (in promise) TypeError: data.map is not a function", which I would like to have display the data retrieved.
您的初始状态是,
yearlyBonds: []
当组件首次呈现时,它采用初始状态。最初你有空数组。所以对空数组的迭代会给你错误。
您可以有条件地添加您的组件,例如,
{ this.state.yearlyBonds.Bonds && <ListTable data={this.state.yearlyBonds.Bonds} />}
Note that, componentDidMount
gets called after 1st render (when component mounts into DOM).
组件的工作流程如下 -
在第一次渲染期间,您有一个状态 -
状态={
每年债券:[]
}
在渲染函数中,您想要传递 Bonds
关键数据,这些数据在您的初始状态中不存在,直到进行 API 调用并且状态具有 Bonds
数据。
由于 this.state.yearlyBonds.Bonds
在初始渲染期间未定义,因此无法在 undefined
对象上调用 map
方法。 这就是您看到该错误的原因。
Now to fix this, there are quite a few methods:
方法#1(最简单):
像这样更新你的状态 -
state = {
yearlyBonds: {
bonds: []
}
}
您的渲染无需任何额外更改即可工作。
方法#2(中等):
更新您的函数以接受具有默认值 data
的解构道具
function ListTable({ classes, header, data=[] }) {
// rest of the code goes here
方法#3:(API 调用的正确方法):
在您的组件状态中添加一个 isLoading
标志。我们将使用它来显示回退 'Loading ...' UI 直到我们有来自 API.
的数据
state = {
yearlyBonds: [],
isLoading: false,
}
在 API 调用之前,更新您的状态 'isLoading' 设置为 true。
componentDidMount() {
// update state
this.setState({ isLoading: true });
axios.get(
'http://localhost/Stamdata.Web/LeagueTable/YearlyManagersJSON',
{ withCredentials: true }
)
.then(res => {
const yearlyBonds = res.data;
// set isLoading to false, as data is received
this.setState({ yearlyBonds, isLoading: false });
})
}
最后在 render 方法中,读取 isLoading
状态并渲染回退。
// rest of the code
render() {
if (this.state.isLoading) {
return <div> Loading ... </div>;
// when data is available
return (
// Tags removed for simplicity
<ListTable data={this.state.yearlyBonds.Bonds} />
我使用 ASP.NET 创建了一个 API,并且我有一个网站 运行 React。我想使用 Axios 显示从 API 到 React 的获取请求检索的数据。该网站有使用两个 cookie 的身份验证方法。我可以让 Axios 从 https://jsonplaceholder.typicode.com/users 获取数据,但是当我使用相同的代码时,我会收到错误消息:Uncaught (in promise) TypeError: data.map is not a function.
我试过如上所述使用占位符,效果很好,但似乎无法从我的 API 获取数据,这让我相信问题出在 cookie 上.我还尝试了一些 Google 搜索,返回结果是我应该包含 withCredentials: true,但这并不能解决问题。
这是我 API 的函数:
public JsonResult YearlyManagersJSON(int year = 0)
{
if (year < 2000 || year > DateTime.Today.Year)
year = DateTime.Today.Year;
var startDate = new DateTime(year, 1, 1);
var endDate = new DateTime(year + 1, 1, 1);
var bonds = this.getOverviewData(ReportType.BONDS, startDate, endDate);
var bondsSum = bonds.Sum(m => m.Aggregate);
var viewData = new TopLeadManagerViewData
{
Title = String.Format("Top Managers in {0}", startDate.Year),
Currency = SiteHelper.getCurrencyToUse(),
Bonds = Enumerable.Select(bonds, m => new ManagerSummary()
{
NumberOfIssues = (int)m.Aggregate2,
TotalAmount = m.Aggregate * 1000000,
Name = m.Group.ToString(),
Share = 100.0m * m.Aggregate / bondsSum
}),
};
return this.Json(viewData, JsonRequestBehavior.AllowGet);
}
This returns a JSON,我已经使用 Postman 检查过了。然后我尝试使用 axios 访问数据。
state = {
yearlyBonds: []
}
componentDidMount() {
axios.get(
'http://localhost/Stamdata.Web/LeagueTable/YearlyManagersJSON',
{ withCredentials: true }
)
.then(res => {
const yearlyBonds = res.data;
this.setState({ yearlyBonds });
})
}
render() {
return (
// Tags removed for simplicity
<ListTable data={this.state.yearlyBonds.Bonds} />
然后将数据向下传递到组件中
function ListTable(props) {
const { classes, header, data } = props;
return(
// Tags removed for simplicity
<TableBody>
{data.map((x, i) => {
return(
<TableRow key={i}>
<TableCell scope="row">{x.Name}</TableCell>
<TableCell scope="row">{x.TotalAmount}</TableCell>
<TableCell scope="row">{x.Share}</TableCell>
<TableCell scope="row">{x.NumberOfIssues}</TableCell>
</TableRow>
)
})}
</TableBody>
所以,这个 returns 错误
"Uncaught (in promise) TypeError: data.map is not a function", which I would like to have display the data retrieved.
您的初始状态是,
yearlyBonds: []
当组件首次呈现时,它采用初始状态。最初你有空数组。所以对空数组的迭代会给你错误。
您可以有条件地添加您的组件,例如,
{ this.state.yearlyBonds.Bonds && <ListTable data={this.state.yearlyBonds.Bonds} />}
Note that,
componentDidMount
gets called after 1st render (when component mounts into DOM).
组件的工作流程如下 -
在第一次渲染期间,您有一个状态 -
状态={ 每年债券:[] }
在渲染函数中,您想要传递
Bonds
关键数据,这些数据在您的初始状态中不存在,直到进行 API 调用并且状态具有Bonds
数据。由于
this.state.yearlyBonds.Bonds
在初始渲染期间未定义,因此无法在undefined
对象上调用map
方法。 这就是您看到该错误的原因。
Now to fix this, there are quite a few methods:
方法#1(最简单):
像这样更新你的状态 -
state = {
yearlyBonds: {
bonds: []
}
}
您的渲染无需任何额外更改即可工作。
方法#2(中等):
更新您的函数以接受具有默认值 data
function ListTable({ classes, header, data=[] }) {
// rest of the code goes here
方法#3:(API 调用的正确方法):
在您的组件状态中添加一个 isLoading
标志。我们将使用它来显示回退 'Loading ...' UI 直到我们有来自 API.
state = {
yearlyBonds: [],
isLoading: false,
}
在 API 调用之前,更新您的状态 'isLoading' 设置为 true。
componentDidMount() {
// update state
this.setState({ isLoading: true });
axios.get(
'http://localhost/Stamdata.Web/LeagueTable/YearlyManagersJSON',
{ withCredentials: true }
)
.then(res => {
const yearlyBonds = res.data;
// set isLoading to false, as data is received
this.setState({ yearlyBonds, isLoading: false });
})
}
最后在 render 方法中,读取 isLoading
状态并渲染回退。
// rest of the code
render() {
if (this.state.isLoading) {
return <div> Loading ... </div>;
// when data is available
return (
// Tags removed for simplicity
<ListTable data={this.state.yearlyBonds.Bonds} />