Search code examples
meteorreactjsflow-router

Meteor - rendering a blaze template within a react template?


This should be a simple question -

Say I have a simple Meteor app using the react package.

I have a root.html file and have flow-router which renders a JSX template on the '/' route.

Say I want my JSX template to embed a blaze-template.

How would I do this?

Take for example the following code:

# test.js
<template name="Test">
Hello world
</template>

...

# root.jsx
Root = React.createClass({
  render() {
    return(
      <div>
      {this.props.content}
      </div>
    )
  }
})

...

# routes.jsx
FlowRouter.route("/", {
  name: "root",
  action: function(params, queryParams) {
    ReactLayout.render(Root,
      {content: <Test />})
  }
})

But with this code, I get a client-side error about not being able to find <Test />.


Solution

  • Ah well I figured this out.

    I also figured how the inverse (how to render react templates from within blaze)

    So to render blaze from react, you make a wrapper class:

    AccountsWrapper = React.createClass({
      componentDidMount() {
        this.view = Blaze.render(Template.Accounts,
          React.findDOMNode(this.refs.container));
      },
      componentWillUnmount() {
        Blaze.remove(this.view);
      },
      render() {
        // Just render a placeholder container that will be filled in
        return <span ref="container" />;
      }
    });
    

    This references a blaze template defined in accounts.html:

    <template name="Accounts">
      {{> loginButtons }}
      <div>
        {{> React component=Test}}
      </div>
    </template>
    

    In my routes file, I render the wrapper template like so:

    FlowRouter.route("/", {
      name: "root",
      action: function(params, queryParams) {
        ReactLayout.render(Root,
          {content: <AccountsWrapper />})
      }
    })
    

    You can also see that in my blaze template I'm calling

    {{> React component=Test}}
    

    This depends on the react-template-helper package and I wrap the react template using the following code (in JSX:

    Test = React.createClass({
      render() {
        return <div>
        WORKING
        </div>
      }
    })
    
    if (Meteor.isClient) {
      Template.Accounts.helpers({
        Test() {
          return Test;
        }
      })
    }