首页 > 解决方案 > Uncaught (in promise) TypeError: Cannot read property of undefined, when try to catch API data in ReactJs

问题描述

我正在使用 ReactJS 开发货币转换器应用程序。该计划是关于从一种货币转换为另一种货币。该应用程序有一个表单,其中包含一个带有提交按钮的字段。此外,它还默认使用初始货币“10 美元”。

当用户在字段中输入货币缩写(例如:KRW)并单击提交按钮时。表格下方将显示从美元转换为韩元的结果。如果用户想添加更多货币,另一种选择货币将显示在“KRW”转换结果下方。

当我试图在用户提交字段中的货币缩写时显示结果时。

这是错误:

Uncaught (in promise) TypeError: Cannot read property 'rates' of undefined
    at Currency.render (App.js:402)
    at finishClassComponent (react-dom.development.js:15319)
    at updateClassComponent (react-dom.development.js:15274)
    at beginWork (react-dom.development.js:16262)
    at performUnitOfWork (react-dom.development.js:20279)
    at workLoop (react-dom.development.js:20320)
    at renderRoot (react-dom.development.js:20400)
    at performWorkOnRoot (react-dom.development.js:21357)
    at performWork (react-dom.development.js:21267)
    at performSyncWork (react-dom.development.js:21241)
    at requestWork (react-dom.development.js:21096)
    at scheduleWork (react-dom.development.js:20909)
    at Object.enqueueSetState (react-dom.development.js:11595)
    at App.push../node_modules/react/cjs/react.development.js.Component.setState (react.development.js:336)
    at Object.App.addCurrency [as onSubmit] (App.js:34)
    at Form.handleSubmit (App.js:204)

这是我的代码:

class Currency extends React.Component {
render() {
        const p = this.props;
        return (
            <div className="currency">
                {/*<span className="currencyText">&#x3C;Currency/&#x3E;</span>*/}
                <div className="currencyInfo">
                    <div>{"1 "+p.base + " = " }</div>
                    <div>{p.data.rates}</div> {/*this is (App.js:402)*/}

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

取而代之的是,如果我像这样编写 Apps.js:402 代码:

<div>{p.data}</div>

并运行应用程序,并在 chrome 中检查控制台,该行的结果为空。

我的意思是图片上的数据:

控制台结果

这是控制台道具 p 的结果:

console.log 中 prop p 的结果

任何解决方案,以便我可以从货币中检索数据速率?

标签: javascriptreactjs

解决方案


理想情况下,您需要某种方式来管理组件中的状态loadingno-data状态,具体取决于您的 api 在没有数据时返回的内容 - 您可能必须以不同的方式管理它,但这也是您应该涵盖的场景。您的数据似乎来自一个名为ratesnot的道具data,它是一个具有多个键的对象。

我不确定您的代码的结构,但是这种迭代和检查加载/无数据状态也可能在父组件中完成。

    class Currency extends React.Component {
    render() {
            const p = this.props;
            const { rates = {} } = p;
            const hasData = Object.keys(rates).length > 0;
            return !p.loading ? (
                <div className="currency">
                    <div className="currencyInfo">
                        { hasData ?
                        <>
                          <div>{"1 "+p.base + " = " }</div>
                          {Object.entries(rates).map(([k, v]) => <div key={k}>{`${k}: ${v}`}</div>)}
                        </> : <p>No data available</p>
                        }
                    </div>
                </div>
            ) : <Loader />
        }
    }

在父组件中,您可以执行以下操作:

    class ParentComp extends React.Component {
      public state = { loading: true, rates: {} };

      componentDidMount() {
        await this.fetchData(...); // could set loading to false on success
      }

      render() {
        const { rates = {} } = this.state;
        const hasData = Object.keys(rates).length > 0;
        return (
          !this.state.loading ?
            hasData ?
              Object.entries(rates).map(([k, v]) => <Currency key={k} name={k} value={v} ... />)
              : <p>No data available</p>
            : <Loader />
        );
      }
    }

然后在您的子组件中:

class Currency extends React.Component {
  render() {
    return  (
      <div className='currency'>
        <div className='currencyInfo'>
            <div>{`${this.props.name}: ${this.props.value}`}</div>
        </div>
      </div>
    );
  }
}

学分:

感谢@Codebling 指出v键中不必要的(值)添加


推荐阅读