首页 > 解决方案 > React 不会访问嵌套状态

问题描述

我已将 React 状态设置为来自 API 的数据

this.setState({loan: response.data})

response.data 是一个嵌套对象

{
  application: {
    amount: 20,
    interest: 10,
    guarantor: {
      firstName: "John",
      lastName: "Doe"
    }
  },
  userId: "123"
}

通常在渲染函数内部我可以访问

<p>{this.state.loan.userId}</p>
<p>{this.state.loan.application.amount}</p>
<p>{this.state.loan.application.guarantor.firstName}</p>

现在我只能访问贷款的第一个孩子。除了我实际上为对象中的每个单独项目设置状态。注意console.log(this.state.loan.application.guarantor)工作正常。

这是 API 调用

fetch(`http://localhost:8000/api/v1/loans/${this.state.id}`)
    .then(res => {
      return res.json();
    }).then(response => {
      this.setState({loan: response.data});
    })
    .catch(err => console.log(err));
const {loan} = this.state;
<div className="col-md-4">
    <h5 className="title">Full Name</h5>
    <p>{loan.fullName}</p>
    <h5 className="title mt-3">Account Number</h5>
    <p>{loan.accountNumber}</p>
    <h5 className="title mt-3">Phone Number</h5>
    <p>Phone Number</p>
</div>
<div className="col-md-4">
    <h5 className="title">Loan Amount</h5>
    <p>
        {(loan.application.amount).toLocaleString("en-NG", {
        style: "currency",
        currency: "NGN"
        })}
    </p>
    <h5 className="title mt-3">Interest Rate</h5>
    <p>{loan.interestRate}%</p>
    <h5 className="title mt-3">Duration</h5>
    <p>{loan.duration} Months</p>
</div>

API 调用的响应

{
            "application": {
                "guarantor1": {
                    "fullName": "Ayebakuro Ombu",
                    "residentialAddress": "30 Udengs Eradiri Avenue Off Azikoro Village Road",
                    "occupation": "Accountant",
                    "netIncome": "50000",
                    "placeOfWork": "Dreamworld",
                    "employer": "Ayebakuro Ombu",
                    "relationship": "Employer",
                    "bvn": "0101010101",
                    "bank": "GTBank",
                    "accountNumber": "10101010101",
                    "phoneNumber": "010101010101"
                },
                "guarantor2": {
                    "fullName": "Ayebakuro Ombu",
                    "residentialAddress": "B48 Copa Cobana Estate, Wumba, Lokogoma",
                    "occupation": "business man",
                    "netIncome": "500000",
                    "placeOfWork": "Dreamworld",
                    "employer": "SafeScrow Tech",
                    "relationship": "Employer",
                    "bvn": "0101010101",
                    "bank": "GTBank",
                    "accountNumber": "0101010101",
                    "phoneNumber": "0101010101"
                },
                "mode": {
                    "name": "DreamWorld Savings And Loans Ltd",
                    "address": "30 Udengs Eradiri Avenue Off Azikoro Village Road",
                    "netIncome": "50000"
                },
                "bankDetails": {
                    "bank": "Parallex Bank",
                    "accountNumber": "0101010101",
                    "bvn": "0101010101"
                },
                "amount": 200000,
                "number": "25642",
                "date": "2019-03-22T02:37:58.069Z",
                "purpose": "For debt payment"
            },
            "approval": {
                "amount": 0,
                "status": "Pending"
            },
            "issue": {
                "status": false
            },
            "payment": {
                "schedule": [],
                "completed": false
            },
            "_id": "5c944a86abf7ea09c40301e5",
            "accountNumber": "1000000002",
            "fullName": "Ayebakuro Ombu",
            "type": "Business",
            "duration": 5,
            "interestRate": 10,
            "__v": 0
        }

错误:LoanPage.js:61 Uncaught TypeError: Cannot read property 'amount' of undefined at LoanPage.render (LoanPage.js:61)

正确记录 this.state.loan.application.amount 日志

标签: javascriptreactjs

解决方案


当一个组件被渲染时(如以下代码),Reactrender立即调用相应组件的方法。

ReactDom.render(<LoanPage />, element);

fetch如果您要在构造函数或方法中执行异步事件,则componentWillMount不会阻止 React 系统执行渲染。

这就是你应该如何处理这个问题。在构造函数/componentWillMount 中,您应该设置this.state.loading = true,然后触发 fetch 调用。在.thenfetch 调用部分,setState 清除加载标志,如下所示:

this.setState({
    loading: false,
    loan: response.data
});

LoanPage的render方法现在可以从“获取调用进行中”的知识中受益,如下所示:

render() {
    if(this.state.loading) {
        return (<h3>Loading...</h3>);
    }

    return (
        <div> Loan amount is {this.state.loan.application.amount} </div>
    );
}

您可以更改渲染的第一部分(在 if 条件下)以显示微调器或类似的东西。您应该更改第二部分以渲染您现在正在渲染的所有内容。


推荐阅读