首页 > 解决方案 > 当状态变量改变时使用 useQuery

问题描述

我在反应应用程序中有以下结构:

<SomeProvider id={objectId}>
  <SomeApp />
</SomeProvider>

此提供程序使用 auseQuery从后端获取对象。有了useContext我,应用程序的所有组件都可以访问它:

const EventProvider = ({ id, children }) => {
  const {data} = useQuery(SOME_QUERY, { variables: input })
  const obj = data ? data.something : {}

  // etc.
}

export const useSomething = () => {
  // etc.
}

在一个组件中,我可以访问这个对象:

const Component = ({id}) => {
  const { obj } = useSomething()
}

直到这里所有工作。我的问题是,在这个组件中,我有一个按钮可以在后端更改这个对象。

如何再次获取 obj?

我当然可以刷新页面,但这是我想避免的解决方案。到目前为止我尝试过的是:

尝试在Component.

 const Component = ({id}) => {
   const { obj } = useSomething()

   const {data} = useQuery(SOME_QUERY, { variables: input })
      const obj = data ? data.something : {}
 }

但实际上我想做的是在状态变量更改时触发查询:

const Component = ({id}) => {
  const { obj } = useSomething()
  const { isActivated } = useOtherHook()

  const {data} = useQuery(SOME_QUERY, { variables: input })
      const obj = data ? data.something : {}

  useEffect(() => {
    // when isActivated changes, I would like to fetch the obj again
  }, [isActivated])
}

如果我使用useQueryinside of useEffect,我会得到:

Hooks can only be called inside of the body of a function component

解决这一挑战的最佳方法是什么?

标签: reactjsreact-hooks

解决方案


您收到错误消息的原因是,您只能在组件主体中使用钩子,而不是在不是钩子的其他函数内部,也不能在条件内部使用。您可以在钩子规则中阅读更多相关信息

正如您在useQuery 此处的文档中所读到的,有多种方法可以使数据保持最新或重新获取。


保持数据最新的最简单方法是使用 apollo 的轮询功能。

const { loading, error, data } = useQuery(QUERY, {
    variables: input,
    skip: !isActivated,
    pollInterval: 500, // Update every 500ms
  });

按需重新获取的一种方法是使用返回的refetch函数。

const { loading, error, data, refetch } = useQuery(/* ... */);
useEffect(() => { refetch() }, [isActivated])

根据您的需要,您也可以使用useLazyQuery挂钩。这不会在渲染时获取数据,而只会在函数调用时获取数据。当您只想在设置或更改输入时请求数据时,这非常有用。

const [getData, { loading, data }] = useLazyQuery(QUERY);

useEffect(() => { getData({ variables: input }) }, []);

推荐阅读