首页 > 解决方案 > 在api请求准备好之前无法弄清楚如何跳过查询,因此它不会在带有useSWR的apollo useQuery中返回未定义的变量

问题描述

我有以下代码使用useSWR访问用户api,如果我控制台记录用户前两次它呈现未定义。useQuery 抱怨user.id是未定义的,这在渲染中的某些时候是正确的,但是我尝试传递一个跳过选项,它可以为具有类似问题的 cookie 变量传递一个跳过选项,或者我不知道如何传递两个变量来跳过,或者它只能取一个,或者它不能一起工作。

到目前为止,这是我的代码

import Layout from "../components/Layout";
import { useForm } from "react-hook-form";
import useSWR from "swr";
import { gql, useQuery } from "@apollo/client";
import { useState, useEffect } from "react";

export const CATALOG_VALUES = gql`
  query GetCatalogValues($id: ID!) {
    findUserByID(id: $id) {
      catalog {
        decor
        clothing
        supplies
        furniture
        _id
      }
      email
    }
  }
`;

const fetcher = (url) => fetch(url).then((r) => r.json());

export default function Welcome() {
  const { data: user, error: userError } = useSWR("/api/user");

  const { data: cookieData, error: cookieError } = useSWR(
    "/api/cookie",
    fetcher
  );

  var cookieBearer = `Bearer ${cookieData}`;

  const { loading, error, data } = useQuery(CATALOG_VALUES, {
    variables: { id: user.id },
    context: {
      headers: {
        authorization: cookieBearer,
      },
    },
    skip: !cookieBearer || !user, // I have tried many different things here
  });

  const { register, handleSubmit, errors } = useForm();
  const onSubmit = (data) => console.log(data);
  console.log(errors);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>{error.message}</p>;
  if (cookieError) return <p>Cookie Error</p>;
  if (!user) return <p>loading</p>;
  if (userError) return <div>failed to load</div>;

  return (
    <Layout>
      <h1>Add your Catalog Type Below</h1>
      {user.id}
      <form onSubmit={handleSubmit(onSubmit)}>
        <h2>Decor</h2>
        <input
          name="Add Form"
          type="radio"
          value="Decor"
          ref={register({ required: true })}
        />

        <div>
          <input type="submit" />
        </div>
      </form>
    </Layout>
  );
}

标签: javascriptreactjsgraphqlnext.jsapollo

解决方案


创建一个组件并传递道具修复它

const Form = ({ cookieBearer, user }) => {
  const { loading, error, data } = useQuery(CATALOG_VALUES, {
    variables: { id: user.id },
    context: {
      headers: {
        authorization: cookieBearer,
      },
    },
  });

  console.log(data);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>{error.message}</p>;

  return <p>hello world</p>;
};
 {cookieBearer && user && <Form cookieBearer={cookieBearer} user={user} />}

推荐阅读