TypeError与“无法读取未定义的属性'length'”

时间:2019-12-23 08:33:05

标签: reactjs aws-amplify

添加async function getNumbers(owner)后,出现以下错误

  71 | <div className="App">
  72 |   Messages for user: {owner}
  73 |   <h3>Numbers</h3>
> 74 |   <div>
     | ^  75 |     {state.numbers.length > 0 ? (
  76 |       state.numbers.map(number => <p key={number.to}>{number.to}</p>)
  77 |     ) : (

原因似乎是由async function getNumbers(owner)引起的。

import Amplify, { Auth, API, graphqlOperation } from "aws-amplify";
import React, { useEffect, useReducer, useState } from "react";

import { withAuthenticator } from "aws-amplify-react";
import { messagesByToByCreatedAt, numberByOwnerByTo } from "./graphql/queries";
import awsconfig from "./aws-exports";

import "./App.css";

Amplify.configure(awsconfig);

// Action Types
const QUERY = "QUERY";

const initialState = {
  messages: [],
  numbers: []
};

const reducer = (state, action) => {
  switch (action.type) {
    case QUERY:
      return { ...state, messages: action.messages, numbers: action.numbers };
    default:
      return state;
  }
};

function App() {
  const [owner, setOwner] = useState(null);
  const [state, dispatch] = useReducer(reducer, initialState);

  useEffect(() => {
    // Get all numbers that belong to user
    async function getNumbers(owner) {
      const ownerData = await API.graphql(
        graphqlOperation(numberByOwnerByTo, { owner: owner })
      );

      dispatch({
        type: QUERY,
        numbers: ownerData.data.numberByOwnerByTo.items
      });
    }
    getNumbers("13d8fbce-8989-4dff-bdcf-2fac8926a52d");

    // getMessages
    async function getMessages(number) {
      const messageData = await API.graphql(
        graphqlOperation(messagesByToByCreatedAt, { to: number })
      );

      dispatch({
        type: QUERY,
        messages: messageData.data.messagesByToByCreatedAt.items
      });
    }
    getMessages("4915735992273");

    // Assign logged in user to $owner
    Auth.currentAuthenticatedUser({
      bypassCache: false
    })
      .then(user => {
        setOwner(user.username);
      })
      .catch(err => console.log(err));
  }, []);

  return (
    <div className="App">
      Messages for user: {owner}
      <h3>Numbers</h3>
      <div>
        {state.numbers.length > 0 ? (
          state.numbers.map(number => <p key={number.to}>{number.to}</p>)
        ) : (
          <p>Add numbers!</p>
        )}
      </div>
      <h3>Messages</h3>
      <div>
        {state.messages.length > 0 ? (
          state.messages.map(message => (
            <p key={message.from}>{message.messageBody}</p>
          ))
        ) : (
          <p>Add messages!</p>
        )}
      </div>
    </div>
  );
}

export default withAuthenticator(App, true);

这是我该如何解决的。感谢@Arun K

useEffect(() => {
    // getMessages
    async function getData(number, owner) {
      const messageData = await API.graphql(
        graphqlOperation(messagesByToByCreatedAt, { to: number })
      );
      const ownerData = await API.graphql(
        graphqlOperation(numberByOwnerByTo, { owner: owner })
      );

      dispatch({
        type: QUERY,
        numbers: ownerData.data.numberByOwnerByTo.items,
        messages: messageData.data.messagesByToByCreatedAt.items
      });
    }
    getData("4915735992273", "13d8fbce-8989-4dff-bdcf-2fac8926a52d");

1 个答案:

答案 0 :(得分:0)

在我看来ownerData.data.numberByOwnerByTo.items返回undefined。主要问题似乎是那个。你应该解决这个问题。

然后,您的减速器将undefined分配给numbersnumbers: action.numbers

如果未定义该值,则可以分配该值,也可以将其设置为空数组

return { ...state, messages: action.messages, numbers: action.numbers || [] };

状态也更新两次,一次在每次api调用之后更新一次,这就是为什么在渲染组件以进行numbers状态更新时undefinedmessages的原因。

在获取消息和数字后,您能否进行一次状态更新?

dispatch({
  type: QUERY,
  numbers: ownerData.data.numberByOwnerByTo.items,
  messages: messageData.data.messagesByToByCreatedAt.items
});