6

Trying to learn React JS / JSX at the moment and have gotten stuck creating a simple login form:

/**
* @jsx React.DOM
*/

var loginForm = React.createClass({
    getInitialState: function() {
        return {loggedIn : false};
    },
    login : function(event) {
        alert('logging in');
    },
    logout : function(event) {
        alert('logging out');
    },
    render: function() {
        return (
            <div>
                <form /*action={this.server+'/login.php'}*/>
                    <label htmlFor="username">Username:</label>
                    <input type="text" id="username" name="username" />
                    <label htmlFor="password">Password:</label>
                    <input type="password" id="password" name="password" />
                </form>
            </div>
            <div>
                <button onClick={this.login}> Login </button>
                <button onClick={this.logout}> Logout </button>
            </div>
        )
    }



});

React.renderComponent(
  <loginForm />,
  document.body
);

If I remove the <button> tags it works fine but otherwise an error is thrown:

Uncaught Error: Parse Error: Line 27: Unexpected identifier

<button onChange={this.logout}> Logout ... ^

fiddle: http://jsfiddle.net/4TpnG/90/

1
  • 1
    I changed your title in hopes people will find it on google easier. Commented May 5, 2014 at 6:51

3 Answers 3

14

You're trying to return two divs from the function. In the docs it says:

Currently, in a component's render, you can only return one node; if you have, say, a list of divs to return, you must wrap your components within a div, span or any other component.

Don't forget that JSX compiles into regular js; returning two functions doesn't really make syntactic sense. Likewise, don't put more than one child in a ternary.

So you can fix it by wrapping your two root divs in a single div; or moving your second root div (with the buttons) into the first one.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Seems I missed this point which makes a lot of sense in terms of components->dom
1
<div>
    <form /*action={this.server+'/login.php'}*/>
            <label htmlFor="username">Username:</label>
            <input type="text" id="username" name="username" />
            <label htmlFor="password">Password:</label>
            <input type="password" id="password" name="password" />
   </form>
   <div>
      <button onClick={this.login}> Login </button>
      <button onClick={this.logout}> Logout </button>
   </div>
</div>

Try using this, seems it wont work if you have two divs/nodes

Comments

1

You can do:

return ([
    <div>
        <form /*action={this.server+'/login.php'}*/>
            <label htmlFor="username">Username:</label>
            <input type="text" id="username" name="username" />
            <label htmlFor="password">Password:</label>
            <input type="password" id="password" name="password" />
        </form>
    </div>, // note the comma
    <div>
        <button onClick={this.login}> Login </button>
        <button onClick={this.logout}> Logout </button>
    </div>
]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.