"Cannot read property 'length' of undefined" 的类型错误

TypeError with "Cannot read property 'length' of undefined"

添加后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");

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

那么你的减速器正在将 undefined 分配给 numbersnumbers: action.numbers

如果它不是未定义的,你可以分配这个值,或者将它设置为一个空数组

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

状态也更新两次,每次 api 调用后更新一次,这就是为什么 numbers 在为 messages 状态更新呈现组件时 undefined .

你能不能在获取消息和号码后做一个状态更新。

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