Apollo GraphQL Деконструкция данных не работает - PullRequest
1 голос
/ 03 апреля 2020

Я копаю graphql, поэтому я следовал учебнику, и я застрял в этой части.

Home. js

function Home() {
  const {
    loading,
    data: { getPosts: posts }   // <===## Here ##
  } = useQuery(FETCH_POSTS_QUERY);

  return (
      <div>
        {loading ? (
          <h1>Loading posts..</h1>
        ) : (
          posts &&
          posts.map((post) => (
            <p>
              {post.content}
            </p>
          ))
        )}
      </div>
  );
}

const FETCH_POSTS_QUERY = gql`
  {
    getPosts {
      id
      content
    }
  }
`;


export default Home;

resolver

  Query: {
    async getPosts() {
      try {
        const posts = await Post.find().sort({ createdAt: -1 });
        return posts;
      } catch (err) {
        throw new Error(err);
      }
    }
  },

Весь код: https://github.com/hidjou/classsed-graphql-mern-apollo/tree/react10

В приведенном выше примере работает хорошо, и использовать его используйте data: { getPosts: posts } для деконструкции возвращаемых данных. но в моем коде я следовал ему, но я получил ошибку

TypeError: Невозможно прочитать свойство 'getPosts' из неопределенного

Вместо этого, если я кодирую, как показано ниже,

function Home() {
  const {
    loading,
    data // <===## Here ##
  } = useQuery(FETCH_POSTS_QUERY);

  if(loading) return <h1>Loading...</h1>

  const { getPosts: posts } = data // <===## Here ##

  return (
      <div>
        {loading ? (
          <h1>Loading posts..</h1>
        ) : (
          posts &&
          posts.map((post) => (
            <p>
              {post.content}
            </p>
          ))
        )}
      </div>
  );
}

Работает хорошо. Похоже, мой код пытается сослаться на data до его загрузки. Но я не знаю, почему это произошло. Код почти такой же. Разные вещи 1. my code is on nextjs, 2. my code is on apollo-server-express. Другие вещи почти такие же, мой распознаватель использует async/await и вернет posts. Я что-то пропустил?

мой распознаватель, как показано ниже.

 Query: {
    async getPosts(_, { pageNum, searchQuery }) {
      try {
        const perPage = 5
        const posts =
          await Post
            .find(searchQuery ? { $or: search } : {})
            .sort('-_id')
            .limit(perPage)
            .skip((pageNum - 1) * perPage)
        return posts
      } catch (err) {
        throw new Error(err)
      }
    },

1 Ответ

1 голос
/ 03 апреля 2020

Ваш урок может быть устаревшим. В более старых версиях клиента Apollo data изначально был установлен как пустой объект. Таким образом, если ваш код получит доступ к какому-либо свойству, он не взорвется. Хотя это было удобно, оно также не было особенно точным (нет данных, так почему мы предоставляем объект?). Теперь data просто не определено, пока ваша операция не завершится. Вот почему последний код работает - вы не получаете доступ к каким-либо свойствам данных до тех пор, пока loading не станет ложным, что означает, что запрос выполнен и data больше не является неопределенным.

Если вы Если вы хотите объявить о перехвате data, вы можете использовать значение по умолчанию, например:

const {
  loading,
  data: { getPosts: posts } = {}
} = useQuery(FETCH_POSTS_QUERY)

Вы можете даже назначить значение по умолчанию для posts, если хотите.

Просто помните о двух других вещах: во-первых, data останется останется неопределенным, если произойдет ошибка сети, даже после изменения loading на true, поэтому убедитесь, что ваш код учитывает этот сценарий. Два, в зависимости от вашей схемы, если в вашем ответе есть errors, возможно, что весь ваш объект data окажется нулевым. В этом случае вы все еще столкнетесь с проблемой деструктуризации, поскольку значения по умолчанию работают только с неопределенным, а не с нулевым значением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...