You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Storybook交互式生成新Story时含对象类型props报错咨询

解决Storybook交互式故事生成中含React元素Props的报错问题

核心原因

报错根源在于Storybook的交互式生成功能需要将args序列化为合法JSX字符串,但你直接在args里传入了React元素(<Icon component={Share} />)——React元素本质是带内部私有属性的对象,无法被序列化工具正确解析,因此抛出"Objects are not valid as a React child"错误。args的设计初衷是存储可序列化的原始值(字符串、数字、布尔、简单对象),而非React元素这类复杂对象。

可行解决方案

1. 将React元素移到Story的render函数中

把非序列化的React元素从args移除,改用render函数动态渲染子元素,这是最直接的方案:

export const ShareButton: Story = {
  args: {
    width: "34px",
    height: "34px",
    padding: "5px",
    borderRadius: "circle",
    background: colors.primary.white,
    color: colors.primary.blue,
    boxShadow: colors.shadows.section,
    marginRight: "0px",
    onClick: fn(),
  },
  render: (args) => (
    <ShareButton {...args}>
      <Icon component={Share} />
    </ShareButton>
  ),
};

args仅保留可序列化的原始参数,render负责处理React元素的渲染,完美避开序列化问题。

2. 用可序列化参数替代直接传入React元素

如果需要让子元素可通过Storybook UI配置,不要直接传React元素,改用枚举值、字符串等可序列化类型,在组件内部根据参数渲染对应元素:
首先修改组件:

// ShareButton组件定义
type ShareButtonProps = {
  // 其他原有props...
  iconType?: 'share' | 'like'; // 用枚举类型替代直接传Icon组件
};

export const ShareButton = ({ iconType = 'share', ...props }: ShareButtonProps) => {
  // 根据参数映射到对应的Icon组件
  const IconComponent = iconType === 'share' ? Share : Like;
  return (
    <button {...props}>
      <Icon component={IconComponent} />
    </button>
  );
};

然后更新Story:

export const ShareButton: Story = {
  args: {
    width: "34px",
    height: "34px",
    padding: "5px",
    borderRadius: "circle",
    background: colors.primary.white,
    color: colors.primary.blue,
    boxShadow: colors.shadows.section,
    marginRight: "0px",
    onClick: fn(),
    iconType: 'share', // 用可序列化的枚举值
  },
};

这样既保留了配置灵活性,又符合args的序列化要求。

3. 自定义JSX序列化逻辑(不推荐)

可以通过修改react-element-to-jsx-string的配置来处理React元素对象,但需要在Storybook的preview.js中添加自定义逻辑,这种方式容易破坏Storybook的默认行为,仅在前两种方案不可行时考虑:

// .storybook/preview.js
import { addDecorator } from '@storybook/react';
import reactElementToJsxString from 'react-element-to-jsx-string';

addDecorator((story) => {
  // 自定义序列化逻辑,过滤React元素的私有属性
  const modifiedToJSX = (element) => {
    return reactElementToJsxString(element, {
      filterProps: ['_owner', '_store'],
      // 其他自定义配置
    });
  };
  // 替换Storybook内部的序列化方法(需注意版本兼容性)
  return story();
});

这种方案依赖Storybook内部实现,版本更新可能导致失效,需谨慎使用。

内容的提问来源于stack exchange,提问作者Stefanos Faustmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:53:13