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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.