[英]Relay - usePreloadedQuery hook is suspending rendering while mounting with enzyme
尝试对使用usePreloadedQuery
的组件进行单元测试时出现以下错误:
Error: A React component suspended while rendering, but no fallback UI was specified.
Add a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.
我有一个接收查询引用的父组件,它使用usePreloadedQuery
来检索数据,如下所示:
type Props = {
queryReference: PreloadedQuery<parentComponentQuery>,
};
export const ParentComponent = ({ queryReference }: Props) => {
const { data } = usePreloadedQuery(
graphql`
query parentComponentQuery($someId: ID!) {
something(someId: $someId) {
...childComponentFragment
}
}
}
`,
queryReference,
);
return (
<div>
<ChildComponent fragmentRef={data.childData} />
</div>
)
}
这里的queryReference
是通过调用loadQuery
创建的,它由一个内部钩子处理,它是react-resource-router
用于中继资源的useResource
的包装器。
我正在尝试使用 Jest 和 Enzyme 使用以下代码测试此组件:
let queryReference;
const mockRelayPayload = () => {
const environment = createMockEnvironment();
environment.mock.queueOperationResolver((operation) =>
MockPayloadGenerator.generate(operation, {
Something: () => ({
// ... data
}),
}),
);
environment.mock.queuePendingOperation(QUERY, {});
act(() => {
queryReference = loadQuery(environment, QUERY, {}); // fire mocked API call
});
return environment;
};
it('should render correctly', () => {
const environment = mockRelayPayload();
const wrapper = mount(
<RelayEnvironmentProvider environment={environment}>
{/*<Suspense fallback={<div>Loading... </div>}>*/}
<ParentComponent queryReference={queryReference}/>
{/*</Suspense>*/}
</RelayEnvironmentProvider>
);
expect(wrapper.find(Wrapper)).toExist();
});
根据文档测试中继组件:
为了使
usePreloadedQuery
挂钩不挂起,必须调用这些函数:
queueOperationResolver(resolver)
queuePendingOperation(query, variables)
preloadQuery(mockEnvironment, query, variables)
与传递给queuePendingOperation
的相同查询和变量。preloadQuery
必须在queuePendingOperation
之后调用
我正在执行前两个步骤,但我无法从react-relay
导入preloadQuery
,基于 github source/flowtypes 看起来它已被弃用/删除。 所以我使用的是loadQuery
act(() => {
queryReference = loadQuery(environment, QUERY, {}); // fire mocked API call
});
但它会抛出前面提到的错误。
正如您从注释代码中可以看出的那样,我也尝试按照错误中的建议使用<Suspense>
,不幸的是它抛出Error: Enzyme Internal Error: unknown node with tag 2
来自enzyme-adapter-react-16
标签为2的未知节点
经过几天的努力终于找到了问题,它就在这里:
environment.mock.queuePendingOperation(QUERY, {});
act(() => {
queryReference = loadQuery(environment, QUERY, {});
});
这应该是
environment.mock.queuePendingOperation(QUERY, { someId: "value" });
let queryReference;
act(() => {
queryReference = loadQuery(environment, QUERY, { someId: "value" });
});
似乎当您使用queueOperationResolver
时,只有当查询“签名”与您传递给queuePendingOperation
和loadQuery
的查询和变量完全匹配时,它才会解析。
在我的情况下,我传递了一个空变量 object {}
而不是{ someId: "value" }
所以解析器根本没有解析查询。
不幸的是,这里抛出的错误消息不是很有用,而不是说查询永远不会解决它只是告诉你使用<Suspense>
这有点误导。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.