首页 > 解决方案 > 在 Storybook 中使用 React 添加组件特定的外部 js 文件

问题描述

我正在尝试设置故事书,以便从外部文件中提取所有内容,但我遇到的问题是 javascript 文件,因为它在组件构建之前加载文件,因此无法在页面上找到要绑定的元素javascript。我现在的设置是这样的......

我有一个 stories.js 文件,其中包含我要添加的组件

import React from 'react';
import { storiesOf } from '@storybook/react';
import Accordion from './Accordion.js';

storiesOf('Accordion', module)
.add('Accordion Component', () => (
    <Accordion></Accordion>
));

Accordion.js 提取组件所需的所有外部文件和数据。

import React, { Component } from 'react';
import Wrapper from '../Wrapper';
import accordionContent from 'html-loader!Apps/accordion/accordion.html';
import 'Frontend/components/content/accordion/scss/accordion.scss';
import 'Frontend/components/content/accordion/js/accordion.js';

class Accordion extends Component {
    render() {
        return (
            <Wrapper
                file={ accordionContent }
                useModels={{
                    'accordionComponent': {
                        title: 'accordion'
                    }
                }}
            />
        );
    }
}

export default Accordion;

Wrapper 文件是一个编译器,它采用 HTML 文件上的 HTL 标记并将其转换为 HTML,因此我不必运行 AEM。

import React, { useState } from 'react';
import Compiler from 'htl-compiler/dist/compiler-esm';
import 'Frontend/base/sass/base.scss';

async function compileHtlToHtml(htl, resourceData, useModels, 
resourceTypes) {
    const c = new Compiler(htl, resourceData, useModels, 
resourceTypes);
    return c.compile();
}

function createMarkupForReact(prop) {
    return {
        __html: prop
    };
}

const Wrapper = ({ file, options, resourceData, resourceTypes, 
useModels }) => {
    const [html, setHtml] = useState('<div>Loading...</div>');
    const [rendered, setRendered] = useState(false);

    if (!rendered) {
        const component = compileHtlToHtml(
            file,
            resourceData,
            useModels,
            resourceTypes
        );
        component
            .then(res => {
                if (res) {
                    setHtml(res);
                    setRendered(true);
                }
            })
            .catch(err => {
                if (err) {
                    setRendered(false);
                    console.error(err);
                }
            });
    }

    return (
        <div
            className="storybook-wrapper"
            dangerouslySetInnerHTML={createMarkupForReact(html)}
        />
    );
};

export default Wrapper;

问题是 wrapper.js 文件在编译 HTL 后重新呈现组件,因此页面上的任何内容都没有绑定到组件 javascript 文件。

我想弄清楚的是我是否可以延迟加载 js 文件,我尝试了 React.lazy 但仍然遇到同样的问题,或者以某种方式将 js 脚本包含在反应组件中。有没有人试图做这样的事情或对如何做有任何建议?我要避免的是对 javascript 使用 storybook,因为我的想法是,一旦在 AEM 中编译,所有组件都将完全按照需要的方式工作,而我所做的只是将文件拉入 storybook。

标签: javascriptreactjsstorybook

解决方案


推荐阅读