0

I am trying to create a email in React using the MJML email library. It runs off react and I have it all working but I need to render 2 sections rather than 1. When I render 1 it doesn't appear properly on the webpage as I need them to be different sizes.

When I try and wrap the elements within a array the return become null, take out one of the sections and it gets returned.

Any help would be appreciated, here is the code.

render() {
    const { mjAttribute } = this.props
    const content = [this.renderEmailOverhead()]
    const innerContent = [this.renderEmailBanner(), this.renderEmailTitle(), this.renderEmailText(), this.renderEmailDivider]

    return ([
        <Section full-width='full-width' padding-top="0">
            { content }
        </Section>,
        <Section>
            { innerContent }
        </Section>
    ])
}
cmiotk
  • 195
  • 1
  • 2
  • 10

2 Answers2

1

Well, render method of a component can only return one element. so you'll have to wrap it in a divas Zargold mentioned.

Note that MJML component are more than a standard React component.

It has some internal logic not available in a React context. IMO you should generate MJML as standard HTML element and render it with a renderToStaticMarkup then pass it to mjml2html function as a string and mjml will compiles

 return (
   <mjml>
     <mj-body>
       <mj-container>
         ... // your sections goes here
       </mj-container>
     </mj-body>
   </mjml>
 )

Note that I don't think React is the best suited for this kind of work, I would recommend you to use a templating language such as mustache/handlebars which fit better.

iRyusa
  • 384
  • 2
  • 13
  • interesting stuff I don't really know about mjml – Zargold May 11 '17 at 19:17
  • I am using handlebars, however I'm short-handing the HTML experience by using a single element to loop through rather than using tons of code, as these components will be used quite a lot so I'm making it easy to use – cmiotk May 11 '17 at 19:19
  • Also, there will be multiple components within the page which leads me not to be able to do the method that you suggested – cmiotk May 11 '17 at 19:20
  • You can also make some component that render mjml too. – iRyusa May 11 '17 at 21:20
0

You cannot use JSX interspersed with JavaScript like that... you could either do (you must have only one parent/root element).

<div>
<Section full-width='full-width' padding-top="0">
    { content }
</Section>
<Section>
    { innerContent }
</Section>
</div>

Or You could if you insist on using an array for some reason:

renderSection(content, fullWidth){
return (
  <Section
    full-width={fullWidth ? 'full-width' : false}
    style={{paddingTop: fullWidth ? 0 : 'auto'}}
  >
  {content}
  </Section>
)
}
render(){
 let contents = [content, innerContent]
return(
    <div>
    {contents.map(section, i => renderSection(section, i % 2 === 0))
    </div>
)
Zargold
  • 1,892
  • 18
  • 24
  • This seems to work other than the fact that the section isn't full-width and is held at 600px :( – cmiotk May 11 '17 at 19:09
  • Now I have the opposite problem, the section with full-width is taking over everything – cmiotk May 11 '17 at 19:12
  • what is the rendered style for the "full width one" – Zargold May 11 '17 at 19:13
  • I'd recommend making style definitions inside the style={{jsxifiedStyle: 'itsdefinition'}} unless this is impossible for some reason? In which case you can use `className='full-width'` and then set that in CSS – Zargold May 11 '17 at 19:15
  • full-width is at 100% which is correct, but the other section although it doesn't have full-width on is for some reason inheriting it from the other section, although they are in fact completely different sections – cmiotk May 11 '17 at 19:16
  • I've tried the style definitions, they don't seem to work – cmiotk May 11 '17 at 19:16