Jef*_*che 5 typescript apollo react-apollo apollo-client
我使用 Apollo 设置了一个 React 应用程序,以拥有一个处理从网络加载数据的包装器组件,以便下面的每个组件都可以直接从 Apollo 缓存查询数据,而不必担心处理加载状态。因此,我的组件如下所示:
export const COUNT_OFF_ADAPTER_QUERY = gql`
query CountOffAdapterQuery($vampId: ID!) {
vamp(id: $vampId) @client {
id
countingOff
countingOffStartTime
}
}
`;
export const CountOffAdapter: React.FC<{}> = () => {
const vampId = useCurrentVampId();
const {
data: {
vamp: { countingOff, countingOffStartTime }
}
} = useQuery<CountOffAdapterQuery>(COUNT_OFF_ADAPTER_QUERY, {
variables: { vampId }
});
const prev = usePrevious({ countingOff, countingOffStartTime });
const countOff = useCountOff();
useEffect(() => {
// Do react stuff
}, [countOff, countingOff, prev]);
return null;
};
Run Code Online (Sandbox Code Playgroud)
在实践中(在浏览器中),这非常有效,因为在应用程序中 Apollo 会立即从缓存返回数据,因此loading调用的结果useQuery永远不会true,我可以解构数据,在后续挂钩中使用它等。
然而,当需要测试时,似乎MockedProvider 必然返回loading为true,测试编写者无法控制是否跳过该状态(显然我希望这样做)。请注意,当useQuery返回loading到 be时true,渲染我的组件将出错,因为它正在解构data,这是未定义的。因此,我永远无法在测试失败的情况下超过该加载状态。
这是我的测试代码:
it("works", async () => {
(useCurrentVampId as jest.Mock).mockImplementation(
() => "6070dedd58d7bf715eb2a6c5"
);
const component = mount(
<MockedProvider
mocks={[
{
request: {
query: COUNT_OFF_ADAPTER_QUERY,
variables: {
vampId: "6070dedd58d7bf715eb2a6c5"
}
},
result: {
data: {
vamp: {
id: "6070dedd58d7bf715eb2a6c5",
countingOff: true,
countingOffStartTime: 1234
}
}
}
}
]}
addTypename={false}
>
<CountOffAdapter></CountOffAdapter>
</MockedProvider>
);
await wait(0);
component.update();
});
Run Code Online (Sandbox Code Playgroud)
我很好奇是否有办法解决这个问题。如果您可以在查询模拟中指定,那就太好了loading: false,但您不能。
我正在使用Next.js,并且主要进行服务器端渲染,因此我遇到了与您相同的情况,我决定进一步调查一下。看起来 apollo-client 在实际的模拟中提供了延迟属性,例如:
const mock: MockedResponse = {
request: {
query: SomeDocument,
variables: { slug: 'test' },
},
result: { data: fakeData },
delay: 0, // <---------THIS ----------|(number or undefined)
};
Run Code Online (Sandbox Code Playgroud)
但这也没有帮助,所以我更深入地研究了源代码,当我看到以下内容后,一切都变得清晰起来:
const mock: MockedResponse = {
request: {
query: SomeDocument,
variables: { slug: 'test' },
},
result: { data: fakeData },
delay: 0, // <---------THIS ----------|(number or undefined)
};
Run Code Online (Sandbox Code Playgroud)
正如您在这里所看到的,延迟仅用作 setTimeout 的毫秒参数,这是一个异步代码 -> 意味着将在 javascript 队列中的同步代码之后添加(https://developer.mozilla.org/en -US/docs/Web/JavaScript/Event_loop)。因此,为延迟字段提供什么值并不重要。
您问题的最终结论:目前无法跳过加载状态。
| 归档时间: |
|
| 查看次数: |
1382 次 |
| 最近记录: |