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
解决这一挑战的最佳方法是什么?
您收到错误消息的原因是,您只能在组件主体中使用钩子,不能在不是钩子的其他函数内部,也不能在条件内部使用。您可以在钩子规则中阅读更多相关内容
正如您在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)