Ошибка типа с «Не могу прочитать свойство 'длина' неопределенного» - PullRequest
1 голос
/ 23 декабря 2019

После того, как я добавил 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 голосов
/ 23 декабря 2019

Мне кажется, что ownerData.data.numberByOwnerByTo.items возвращает undefined. главная проблема, кажется, в этом. Вы должны это исправить.

тогда ваш редуктор назначает undefined на numbers. numbers: action.numbers

Вы можете присвоить значение, если оно не определено, или установить его в пустой массив

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

Также состояние обновляется дважды, один раз после каждого вызова API, поэтомуnumbers было undefined, когда компонент отображается для обновления состояния messages.

Не могли бы вы сделать одно обновление состояния после получения как сообщений, так и номеров.

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