Meteor + React + CJSX file load order

I’m trying out Meteor + React for the first time, and I’m having an issue with load order. I have a global App.Components where I’m keeping all my React components, but since Meteor has that strict load order, some components aren’t available in other components unless they’re loaded first. This obviously isn’t optimal as I have to use hacks like nest folder in folders, and use _ to move the folder up, etc.

What I really don’t understand is I’ve looked at many Meteor + React example apps and it doesn’t seem like they have the same problem. I’ve read that it shouldn’t be an issue since the render() functions aren’t called until after Meteor.startup which means all the components should be available, if I understood that correctly.

Am I missing something, or is the issue simply using CJSX and at compile time it can’t find the components?

I think I have the same issue but I’m not using coffeescript. I have a component that imports two others from a single Components global.

let PageHelpText = class PageHelpText extends React.Component {

  render () {
    return (
      <div className="page-help-text">
        <p>{this.props.text}</p>
      </div>
    );
  }
};

PageHelpText.propTypes = {
  text: React.PropTypes.string
};

// Expose to other components as `Components.PageHelpText`
_.extend(Components, { PageHelpText });

And when I’m using PageHelpText in other components I simply import it at the top of the file:

let { PageHelpText, TrackingSnippet } = Components;

However, in this case only PageHelpText is available. TrackingSnippet is undefined which I believe is because it’s defined further down (alphabetically) than the component that imports it whereas PageHelpText is above.

If every component is defined globally (and I don’t ‘import’ them at the top) I don’t have the issue.

If I move the import line into the render function it works, it’s only a problem when pulling in the components at the top of the file:

  render () {
    // Moved 'import' from top of file to here and now it works...
    let { PageHelpText, TrackingSnippet } = Components;
    let helpText = this.getHelpText();
    return (
      <div className="wrapper">
        <PageHelpText text={helpText} />
        <TrackingSnippet url={Meteor.settings.public.cdnUrl} />
      </div>
    );
  }
1 Like

Ah, that actually makes sense, thanks Tim. Can’t wait until Meteor can use import/export or something similar.

Yeah, module support in core would be great. To my knowledge it’s not going to be shipped in 1.2. Perhaps 1.3?

However, modules are supported in Meteor right now using https://atmospherejs.com/universe/modules though I’ve not tried it yet. I’m struggling enough with getting up to speed with ES6/ES2015/JSX :smile:

Here’s a great example of it in use — https://github.com/optilude/meteor-react-example

Yep i’ve had the same problem if I do var Button = Comps.Button at the top of most files. Putting this in the render like Tim mentioned solves it. You can also wrap it with a Meteor.startup but that’s pretty ugly.

That looks pretty awesome, I’ll probably try it out today, thanks!

So much to learn, the joys of being a dev :slight_smile: One of the reasons I’m sticking with Coffeescript for now though, since I already know it pretty well and I still prefer the syntax over ES6. Love how CJSX looks.