使用Storyshots渲染React Portal时出错

时间:2018-09-04 09:57:55

标签: reactjs jestjs storybook storyshots

我试图使用门户来渲染模式,它在我的应用程序以及Storybook中都可以正常工作,但是一旦将其添加到Storyshots中,我就会遇到问题。

第一个问题是模拟ReactDOM的createPortal API。我做到了:

ReactDOM.createPortal = element => element;

如果未添加,则会出现以下错误:

  

错误:未被发现[TypeError:parentInstance.children.indexOf不是函数]

我找到了此解决方案React Portal Error

这解决了此问题,但是当组件使用门户网站时,尝试附加子项时失败。它找不到'modal-root'组件,因此无法附加该元素。我不确定该如何克服。

我的门户网站与React网站上的示例几乎相同:

import React from 'react';
import { createPortal } from 'react-dom';
import { node } from 'prop-types';

class Portal extends React.Component {
  constructor(props) {
    super(props);
    this.el = document.createElement('div');
  }

  componentDidMount() {
    // !!!!!!!fails here !!!!!!!!!
    document.getElementById('modal-root').appendChild(this.el);
  }

  componentWillUnmount() {
    document.getElementById('modal-root').removeChild(this.el);
  }

  render() {
    return createPortal(this.props.children, this.el);
  }
}

它现在因以下错误而失败:

  

错误:未捕获[TypeError:无法读取null的属性'appendChild']

上面的代码段中指示的位置。

3 个答案:

答案 0 :(得分:2)

您可以做两种不同的事情:

.storybook中添加一个新的DOM元素:

let modalRoot = document.createElement("div")
modalRoot.setAttribute("id", "modal-root")
document.querySelector("body")!.appendChild(modalRoot)

您还可以做的另一件事是模拟文档,因为问题是您试图找到一个不存在的dom元素。

答案 1 :(得分:0)

here所述,您可以安装rc-util并将以下内容添加到测试的顶部,或者将其添加到jest.setup.js(或package.json jest)中(如果需要全局添加)部分(如果您使用的是此部分)。

jest.mock('rc-util/lib/Portal')

PS。如果您使用CRA,则您的笑话设置文件位于src/setupTests.js

答案 2 :(得分:0)

另一种方法。将以下内容放入您的 jest 设置文件中:

jest.mock('react-dom', () => {
  const original = jest.requireActual('react-dom');
  return {
    ...original,
    createPortal: node => node,
  };
});