繁体   English   中英

中继 - usePreloadedQuery 挂钩在使用酶安装时暂停渲染

[英]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时,只有当查询“签名”与您传递给queuePendingOperationloadQuery的查询和变量完全匹配时,它才会解析

在我的情况下,我传递了一个空变量 object {}而不是{ someId: "value" }所以解析器根本没有解析查询。

不幸的是,这里抛出的错误消息不是很有用,而不是说查询永远不会解决它只是告诉你使用<Suspense>这有点误导。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM