当状态变量改变时使用 useQuery

Alb*_*Mar 8 reactjs react-hooks

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

<SomeProvider id={objectId}>
  <SomeApp />
</SomeProvider>
Run Code Online (Sandbox Code Playgroud)

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

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

  // etc.
}

export const useSomething = () => {
  // etc.
}
Run Code Online (Sandbox Code Playgroud)

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

const Component = ({id}) => {
  const { obj } = useSomething()
}
Run Code Online (Sandbox Code Playgroud)

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

我怎样才能再次获取 obj?

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

尝试在Component.

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

   const {data} = useQuery(SOME_QUERY, { variables: input })
      const obj = data ? data.something : {}
 }
Run Code Online (Sandbox Code Playgroud)

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

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])
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Lin*_*ger 8

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

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


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

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

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

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

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

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

useEffect(() => { getData({ variables: input }) }, []);
Run Code Online (Sandbox Code Playgroud)