如何使用Apollo graphql查询初始化useState

问题描述

在组件渲染之前,如何使用useState并将其设置为从graphql接收的值?

我尝试过:

  const [name,setName] = useState('');
  const [email,setEmail] = useState('');
  

  const [me] = useQuery(gql`
    query Me {
      me {
        id
        name
        email
      }
    }
  `);

  useEffect(() => {
    (async () => {
      const { data } = await me();

      if (data) {
        setName(data.me.name);
        setEmail(data.me.email);
      }
    })();
  },[]);

并收到此错误

TypeError: Object is not a function
Profile
src/pages/Profile.js:51
  48 | const [currentPasswordValid,setCurrentPasswordValid] = useState(false);
  49 | const [open,setopen] = useState(false);
  50 | 
> 51 | const [me] = useQuery(gql`
     | ^  52 |   query Me {
  53 |     me {
  54 |       id

原因我正在尝试将表单输入的值设置为当前用户值:

<TextField value={name} onChange={(e) => setName(e.target.value)} />

解决方法

似乎您使用了错误的钩子。 useQuery将在组件安装后自动执行。它将返回一个dataloading和一个error属性供您使用(如果您在文档中查找,会有更多的属性,但这是基本的属性)。>

如果要手动触发查询,可以使用useLazyQuery钩子,它将返回上面的属性以及可用于执行查询的回调。

使用useQuery,您的代码可以看起来像这样:

const [name,setName] = useState('');
  const [email,setEmail] = useState('');
  

  const { data,loading } = useQuery(gql`
    query Me {
      me {
        id
        name
        email
      }
    }
  `);

  if(loading) {
    return <div>loading...</div>;
  }

  return <TextField value={data.me.name} onChange={(e) => setName(e.target.value)} />;

如果您喜欢使用惰性查询,则您的代码应如下所示:

  const [name,setEmail] = useState('');
  

  const [me,{ data }] = useLazyQuery(gql`
    query Me {
      me {
        id
        name
        email
      }
    }
  `);

  useEffect(() => {
    (async () => {
      await me();
    })();
  },[]);

  useEffect(() => {
    if (data) {
      setName(data.me.name);
      setEmail(data.me.email);
    }
  },[data])

我个人更喜欢避免不必要时使用懒惰查询。