React layout and forms?

Hi,

I’ve been running into a small issue, and I have no idea what’s going wrong and why… This may be my fault for not using it right, but please correct me!

I have my Main layout:

Main = React.createClass({  
  render() {
    return <body>
        <div className="body-wrapper">
            <PersonalMenu />
            <div className="content-wrapper">
                <Header />
            {this.props.content}
            <GameForm />
            <Footer />
            </div>
        </div>
    </body>

  }
});

My GameForm is this

GameForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = this.refs.author.value.trim();
    var text = this.refs.text.value.trim();
    if (!text || !author) {
      return;
    }
    console.log(author);
    console.log(text);
    // TODO: send request to the server
    this.refs.author.value = '';
    this.refs.text.value = '';
    return;
  },

  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

However, when I visit the page, the onSubmit is NOT working at all. The form just gets posted and the page refreshes.

When I change my Main to

Main = React.createClass({
  componentDidMount: function() {
    ReactDOM.render(<GameForm />, document.getElementById("render-target"));
  },

  render() {
    return <body>
        <div className="body-wrapper">
            <PersonalMenu />
            <div className="content-wrapper">
                <Header />
            {this.props.content}
            <div id="render-target"> </div>
            <Footer />
            </div>
        </div>
    </body>

  }
});

The onsubmit works when using the last Main layout. What’s going wrong? Am I doing something wrong? Or what is supposed to happen?

Believe it or not, but I stumbled upon a similar problem. I’m curious if any smart minds can help us out. (:

Wild guess: that <body> tag seems problematic. Don’t use that, use <div> instead.

Doesn’t work, I get

Uncaught Error: Invariant Violation: NoHeaderFooter.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

It is my main layout, so I need to return a body tag.

However, what I’ve noticed, is that somehow when using a component inside a React Layout, all events just get removed. It’s like the parsing of the layout ignores all tags like onSubmit are not taken into consideration.

You don’t need to return a body tag. Typically you would include the static-html package and then have a client/main.html file that looks like:

<head>
  <!-- stuff -->
</head>
<body>
  <div id="app"></div>
</body>

And then you render your React app into #app.

I’ll dump your code into a Meteor project today when I have time and see if it works for me.

Sorry for the late response, but that did seem to fix it, thanks!

1 Like

For those of you using react-layout and get tripped up at this like I did be sure to add static-html package to the project and to not have any body tags in your react.render components. @fxsam @neglexis