title: Adding component specific external js file with React in Storybook
body: <p>I'm trying to set up storybook so it pulls everything from external files but the problem I am having is with the javascript file because it loads the file before the component builds so it can't find the elements on the page to bind to the javascript. My current set up looks like this....</p>
  
  <p>I have a stories.js file that pulls in the component I'm trying to add</p>
  
  <pre><code>import React from 'react';
  import { storiesOf } from '@storybook/react';
  import Accordion from './Accordion.js';
  
  storiesOf('Accordion', module)
  .add('Accordion Component', () =&gt; (
      &lt;Accordion&gt;&lt;/Accordion&gt;
  ));
  </code></pre>
  
  <p>The Accordion.js pulls in all the external files and data I need for the component.</p>
  
  <pre><code>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 (
              &lt;Wrapper
                  file={ accordionContent }
                  useModels={{
                      'accordionComponent': {
                          title: 'accordion'
                      }
                  }}
              /&gt;
          );
      }
  }
  
  export default Accordion;
  </code></pre>
  
  <p>The Wrapper file is a compiler that takes the HTL markup on the HTML file and converts it to HTML so I don't have to run AEM.</p>
  
  <pre><code>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 }) =&gt; {
      const [html, setHtml] = useState('&lt;div&gt;Loading...&lt;/div&gt;');
      const [rendered, setRendered] = useState(false);
  
      if (!rendered) {
          const component = compileHtlToHtml(
              file,
              resourceData,
              useModels,
              resourceTypes
          );
          component
              .then(res =&gt; {
                  if (res) {
                      setHtml(res);
                      setRendered(true);
                  }
              })
              .catch(err =&gt; {
                  if (err) {
                      setRendered(false);
                      console.error(err);
                  }
              });
      }
  
      return (
          &lt;div
              className="storybook-wrapper"
              dangerouslySetInnerHTML={createMarkupForReact(html)}
          /&gt;
      );
  };
  
  export default Wrapper;
  </code></pre>
  
  <p>The issue is that the wrapper.js file rerenders the component after it compiles the HTL so nothing on the page is bound to the component javascript file.</p>
  
  <p>What I am trying to figure out is if I can either lazy load the js file, I tried React.lazy but still had the same problem, or somehow include the js script within the react component. Has anyone tried to do something like this or have any suggestions of how it might be done? What I am trying to avoid is using storybook for the javascript because the idea is that all the components will work exactly how they are needed once it gets compiled in AEM and all I am doing is pulling the files into storybook.</p>