React:加载 axios 后无法访问数据中的属性。它可能与参数有关吗?

React: Couldn't access properties within data after axios loads. Could it have something to do with params?

我正在编写 MERN 应用程序,我快完成了。但是,我在显示带有数据的单个客户页面时遇到问题。

我的App.js

import React from 'react';
import { BrowserRouter as Router, Route } from "react-router-dom";
import CustomersList from "./components/customers-list";
import customerRewards from './components/customerRewards';
import "bootstrap/dist/css/bootstrap.min.css";

 
function App() {
 return (
 <Router>
    <div className="container">
      <div className="header">
        <h1>Wow Rewards Program</h1>
      </div>
      <Route path="/" exact component={CustomersList} />
      <Route path='/:id' component={customerRewards} />
    </div>
  </Router>
 );
}
 
export default App;

用于在主页中列出客户的我的客户列表组件

import React, { Component } from 'react';
import axios from 'axios';
import CustomerCard from "./customerCard";

class CustomersList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      customers: []
    }
  }

  componentDidMount() {
    axios.get('http://localhost:5000/customers/')
     .then(response => {
       this.setState({ customers: response.data });
     })
     .catch((error) => {
        console.log(error);
     })
  }
  
  
  render() {
    const customers = this.state.customers;
    console.log("customerList", customers);
    let customersList;

    if(!customers) {
      customersList = "there is no customer record!";
    } else {
      customersList = customers.map((customer, k) =>
        <CustomerCard customer={customer} key={k} />
      );
    }

    return (
      <div>
        <h2>Customers List</h2>
        <div>
          <table>
            <thead>
            <tr>
              <th>Account</th>
              <th>Name</th>
              <th>Actions</th>
            </tr>
            </thead>
            <tbody>
              {customersList}
            </tbody>
          </table>
        </div>
      </div>
    )
  }
}

export default CustomersList;

我的 CustomerCard 组件显示每个客户

import React from 'react';
import { Link } from 'react-router-dom';

const CustomerCard = (props) => {
  const  customerCard  = props.customer;

    
    return (
      <tr>
        <td>{customerCard.account}</td>
        <td>{customerCard.name}</td>
        <td>
          <Link to={`/${customerCard.account}`}>view</Link>
        </td>
      </tr>
    )
  
}

export default CustomerCard;

用于列出客户详细信息的我的客户奖励组件

import React, { Component } from 'react';
import { Link} from 'react-router-dom';
import '../App.css';
import axios from 'axios';

class customerRewards extends Component {
  constructor(props) {
    super(props);
    this.state = {
      customerRewards: {}
    };
  }

  componentDidMount() {
    // const { accountId } = this.props.match.params;
    console.log("Print id: " + this.props.match.params.id);
    axios
      .get('http://localhost:5000/customers/'+this.props.match.params.id)
      .then(res => {
        // console.log("Print-customerRewards-API-response: " + res.data);
        this.setState({
          customerRewards: res.data
        })
      })
      .catch(err => {
        console.log("Error from customerRewards");
      })
  };


  render() {

    const customerRewards = this.state.customerRewards;
    console.log("customerID", customerRewards);
    let CustomerItem = <div>
      {customerRewards.purchase_history}
    </div>

    return (
      <div >
        <div className="container">
          <div className="row">
            <div className="col-md-10 m-auto">
              <br /> <br />
              <Link to="/" className="btn btn-outline-warning float-left">
                  Back
              </Link>
            </div>
            <br />
            <div className="col-md-8 m-auto">
              <h1 className="display-4 text-center">Hello {customerRewards.name}</h1>
              <p className="lead text-center">
                  {customerRewards.account}
              </p>
              <hr /> <br />
            </div>
          </div>
          <div>
            { CustomerItem }
          </div>

        </div>
      </div>
    );
  }
}

export default customerRewards;

这是我上传到 MongoDB Atlas 的 .json 示例:

[
  {
    "account": "BCE456",
    "name": "JohnDoe",
    "purchase_history": [
      {
      "month": "Month01",
      "transitions": [
        {
        "date": "01/01/2010",
        "purchase": 120
      },
      {
        "date": "01/01/2010",
        "purchase": 120
      },
      {
        "date": "01/01/2010",
        "purchase": 120
      }
    ]
    },
    {
      "month": "Month02",
      "transitions": [
        {
        "date": "01/01/2010",
        "purchase": 120
      },
      {
        "date": "01/01/2010",
        "purchase": 120
      },
      {
        "date": "01/01/2010",
        "purchase": 120
      }
    ]
    }
  ]
  },
  {
    "account": "ABC123",
    "name": "JohnDoe",
    "purchase_history": [
      {
      "month": "Month01",
      "transitions": [
        {
        "date": "01/01/2010",
        "purchase": 120
      },
      {
        "date": "01/01/2010",
        "purchase": 120
      },
      {
        "date": "01/01/2010",
        "purchase": 120
      }
    ]
    },
    {
      "month": "Month02",
      "transitions": [
        {
        "date": "01/01/2010",
        "purchase": 120
      },
      {
        "date": "01/01/2010",
        "purchase": 120
      },
      {
        "date": "01/01/2010",
        "purchase": 120
      }
    ]
    }
  ]
  }
]

我可以看到我可以在 console.log("customerID", customerRewards); 中下载客户详细信息,但是,当我尝试访问 {customerRewards.name} 时,它根本不会显示名称....

我错过了什么?它可能与我试图 link 的参数有关吗?我试图通过 account 而不是 _id

link

只是select你想取名字的元素:

customerRewards[0].name

你的状态片,customerRewards是一个数组,当它来自API。因此,在这种情况下,即使您使用对象 {} 声明初始状态,customerRewards 也始终是一个只有一个元素的数组。可能是您 API 回复中的问题 - 我不熟悉 MongoDB Atlas 或它是否为您创建访问模式,但您应该能够配置 return 一个单一对象一个唯一的 ID 而不是 1 个元素的数组。

现在你可以做:

this.setState({
  customerRewards: res.data[0] /** could do res.data.shift() as well */
})

如果应该只有一个元素返回,我会弄清楚你为什么要 return 数组。