v1.3 Blaze & React + createContainer issues

Help! I’ve upgraded my application to Meteor v1.3 and while my code is currently a mix of React and Blaze, it seemed to all be working fine until I logged out of my application… Now I can’t login, as both of my submit events handled in the login (Blaze) Template do-not fire when I would expect them too.

My JS: https://gist.github.com/Siyfion/b0befb2c6e1ee488d301
My view: https://gist.github.com/Siyfion/d43ccb06dc9fc6b28a91

It’s almost certainly me doing something stupid, but I just can’t see anything wrong… :confused:

Okay this is sooo weird… If I change the submit button to have a class js-submit and then change the event handler to also fire on a click .js-submit, the event is triggered on button press, just fine.

But the submit event never fires on an enter press and weirdly I don’t seem to be able to change the checked state of the checkbox; the box just shows the mouseDown grey colour and then doesn’t actually check/uncheck. If it’s loaded as checked, it stays checked, and vice-versa.

Ah ha!! Breakthrough.

I have been mixing Blaze and React (as I mentioned) and I converted my first React component to use the createContainer method of data-loading mentioned here: http://guide.meteor.com/react.html#using-createContainer

I also have some react components being loaded from within Blaze, as per here: http://guide.meteor.com/react.html#using-with-blaze

So naturally, when it came to adding the container to blaze I did the same as normal, I created a helper to return the ‘container’ react component.

THIS is what has seemingly caused all these issues. Perhaps @sashko / @benjamn might need to redirect this to the appropriate person!?

I feel like there should be no difference, since the container and mixin approach actually call the same exact code in the end. Can you try going back to the mixin for a specific component and see if that fixes the issue?

As soon as I bypass the container and swap it with the component & directly pass props, it all works fine.

I’d been using the app on 1.3 after switching fine up until I used my first React container component, lots are still loaded and working fine with the mixin. :confused:

And I can confirm if I revert the component back to it’s Mixin version, loaded in exactly the same way, I get no issues at all. It’s got to be something to do with the container!

1 Like

Just to highlight what it is I’m doing:

header.html

<ul class="nav navbar-nav navbar-right">
  {{> React component=AccountHeaderButtonsContainer}}
</ul>

header.js

import { Template } from 'meteor/templating';
import AccountHeaderButtonsContainer from '/client/components/account_header_buttons/account_header_buttons_container.jsx';

Template.header.helpers({
  AccountHeaderButtonsContainer() {
    return AccountHeaderButtonsContainer;
  },
});

account_header_buttons_container.jsx

import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import AccountHeaderButtons from './account_header_buttons.jsx';

export default createContainer(() => {
  const user = Meteor.user();
  return {
    user,
  };
}, AccountHeaderButtons);

I’ve taken a look at: https://github.com/meteor/react-packages/blob/devel/packages/react-meteor-data/createContainer.jsx

And I can’t see anything that would cause this, so I’ll work on creating a small example app that highlights the issue… Perhaps that will help track it down.

Ignore all of this, completely my fault…

Haha, but tell us what the mistake was in case others have made it too. And especially, how you figured it out.

1 Like

Oh god it’s soooo embarrassing…

The first React component that I ported over to using the createContainer strategy was a little “user dropdown” menu that goes up in the navbar. As such it has a toggle state for showing the dropdown, and a (slighty hacky) event handler added on componentDidMount that listens to all click events on the <body> and checks if it originated outside of the dropdown and if so, hides the dropdown. (a bit like clicking outside a modal)

In my conversion, I changed it from being a React.createClass() to a class XXX extends React.Component {} moved lots of code around and tidied things up.

In doing so I accidentally added a line… can you spot it.

  componentDidMount() {
    $('body').on('click', (e) => {
      e.preventDefault();
      const accountDropdown = $('li.dropdown.account-dropdown');
      if (!accountDropdown.is(e.target)
        && accountDropdown.has(e.target).length === 0
        && $('.open').has(e.target).length === 0
      ) {
        accountDropdown.removeClass('open');
      }
    });
  }

Whoooooooops… that e.preventDefault() must have been a copy and paste error on my part, and effectively cancels ALL click events on the body. Oooooops.

1 Like

Haha, that’s a good one. Thanks for sharing :slight_smile:

1 Like