我有点困惑。根据{{3}}以及this SO question的说法,在调用useEffect
钩子填充状态后,我应该能够调用useQuery
钩子,这是通过{{1} }。例如,诸如此类(假设useReducer
,foo
和bar
在对GraphQL服务器的单个请求中被命名为查询):
baz
由于我无法确定的原因,当我在const MyComponent = ( props ) => {
const [ state, dispatch ] = useReducer( reducer, initialState )
const query = someCondition ? query1 : query2
const variables = { variables: someCondition ? query1Vars : query2Vars }
const { loading, error, data } = useQuery( query, variables )
useEffect(function() {
dispatch({
type: types.INIT,
payload: {
foo: data.foo,
bar: data.bar,
baz: data.baz
}
})
}, [data])
return (
<div>
{
(() => {
if ( loading ) return <Loading />
if ( error ) return <Error />
return (
// components that depend on data
)
})()
}
</div>
)
}
中引用data
时,它就是undefined
。我已经检查了我的网络响应,并且对GraphQL端点的调用确实正在返回数据。 (本质上是this question中描述的内容。)
除了条件查询/变量赋值外,此代码还用于其他一些组件,并且可以正常工作,所以我不知道为什么在我的情况下它不起作用。
我不确定这是怎么回事,因为我已经确保没有任何钩子被有条件地调用,这违反了钩子规则;我正在做的是通过Apollo客户端在发送查询之前 有条件地分配变量值。 (我还尝试了useEffect
选项的onCompleted
属性,但没有useQuery
钩子,但无济于事; useEffect
仍然是data
。)>
答案 0 :(得分:1)
除非我不完全了解您的问题,否则这似乎是预期的行为。
useEffect
将在挂载时触发,然后在data
进行任何更改时,data
仅在API调用完成后才会更改。最初的useEffect
调用将在useQuery
得到服务器响应之前发生,因此您不能在useEffect
内部假定将设置data
。
如果您只想在data
时分派,则应保护呼叫,例如
useEffect(() => {
if (data) {
dispatch({
type: types.INIT,
payload: {
foo: data.foo,
bar: data.bar,
baz: data.baz
}
});
}
}, [data]);