如何使用storybook.js预览React Portal组件

5

我使用popper.js实现了一个Popper组件,并使用React的Portal来渲染弹出元素。

现在我想预览我的Popper组件,但是在storybook.js中无法创建portal。

这是我的解决方法。

.storybook/preview.js

import { ThemeProvider } from 'emotion-theming';
import { Global } from '@emotion/react';
import { theme, normalize } from 'custom-theme';

export const parameters = {
  actions: { argTypesRegex: '^on[A-Z].*' },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
};

export const decorators = [
  Story => (
    <>
      <ThemeProvider theme={theme}>
        <Global styles={normalize} />
        {Story()}
        <div id="popper-root"></div>
      </ThemeProvider>
    </>
  ),
];

Portal.tsx

import { ReactNode, useMemo } from 'react';
import { createPortal } from 'react-dom';

interface IPortal {
  children: ReactNode;
  portalId: string;
}

const Portal = ({ children, portalId }: IPortal) => {
  const portalElement = useMemo<HTMLElement | null>(
    () => document.getElementById(portalId),
    [portalId],
  );

  if (!portalElement) {
    throw new Error(`Undefined Portal Id : ${portalId}`);
  }

  return createPortal(children, portalElement);
};

export default Portal;

捕获错误消息

错误图片

有没有办法在Storybook上使用React Portal显示组件?如果没有,除了在React项目中进行测试之外,还有其他预览它的方法吗?

4个回答

1

对我而言,当我在preview-body.html中添加一个div时,它可以工作,如下所示。为了在storybook中反映出这一点,您需要重新启动storybook。

<div id="popper-root"></div>

1
preview-body.html 添加到 preview.js 旁边,并使用以下内容:
<div id="popper-root"></div>

1

我能够通过在我的ComponentStory模板中添加<div id="popper-root"></div>来解决这个问题。

但是,如果我打开portal并渲染story,它无法找到popper-root


0

我在storybook中有一个根元素id可用于门户网站。 我已经将其用于React / Next.js门户网站。 现在它运行良好。

  • Storybook根元素 <div id="docs-root"></div>
  • 门户网站元素选择器 document.getElementById('docs-root)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接