Hello, First Name Last Name I've been working on learning React, and so like most people do when they get started on something new. I created an arbitrary simple project to get a bit more familiar with the concepts.

It's so simple that it shouldn't really require any explanation. Here's the React code.

var TestInput = React.createClass({
    propTypes: {
        id: React.PropTypes.string.isRequired,
        label: React.PropTypes.string.isRequired,
        placeholder: React.PropTypes.string
    },
    getDefaultProps: function() {
        return {
            type: 'text'
        }
    },
    render: function() {

        var {label, id} = this.props;
        var other = _.omit(this.props, 'label');

        return (
            &lt;div className="form-group"&gt;
                &lt;label htmlFor={id}&gt;{label}&lt;/label&gt;
                &lt;input className="form-control" {...other}/&gt;
            &lt;/div&gt;
        );
    }
});

var TestOutput = React.createClass({
    propTypes: {
        name: React.PropTypes.string.isRequired
    },
    render: function() {
        return (
            &lt;h3&gt;Hello {this.props.name}!&lt;/h3&gt;
        );
    }
});

var TestBox = React.createClass({
    getInitialState: function() {
        return {
            firstName: '',
            lastName: ''
        }
    },
    handleInput: function(event) {
        var newState = {};
        newState[event.target.id] = event.target.value;
        this.setState(newState);
    },
    createName: function() {
        var nameParts = [];

        if (this.state.firstName.length == 0 &amp;&amp; this.state.lastName.length != 0) {
            nameParts.push('Mr.');
        }
        if (this.state.firstName.length != 0) {
            nameParts.push(this.state.firstName);
        }
        if (this.state.lastName.length != 0) {
            nameParts.push(this.state.lastName);
        }
        if (nameParts.length == 0) {
            nameParts.push('Anonymous');
        }

        return nameParts.join(' ');
    },
    render: function() {
        return (
            &lt;div className="test-box"&gt;
                &lt;TestInput id="firstName" label="First Name" placeholder="John" onKeyUp={this.handleInput}/&gt;
                &lt;TestInput id="lastName" label="Last Name" placeholder="Smith" onKeyUp={this.handleInput}/&gt;
                &lt;TestOutput name={this.createName()} /&gt;
            &lt;/div&gt;
        );
    }
});

React.render(
    &lt;TestBox/&gt;,
    document.getElementById('container')
);


It works, but it seems like I had to do way too much to get it to work. Not that it was difficult to write, but it just seems like a lot of data transfer and boilerplate to do very little. Maybe this is just because my example is simple and contrived? I'm just thinking that with jQuery I could write a single event handler which works on both input's keyUp and update the H3's text based on the current values.

What am I doing wrong? Or am I doing it right?
React has a small amount of boilerplate you need to repeat in order to keep your components well documented, thus the usage of propTypes which is one of great things to validate data.

There is nothing wrong with how your components are structured, as react "ways" were followed.

Only thing I can observe and which can be improved is to use strict comparisons, eg: === instead of == and so on. Why? 


  The identity operator returns true if the operands are strictly equal (see above) with no type conversion.


More information at MDN

As a bonus if your project uses Babel then you can use const and let for defining variables.

Also you could transform:

var {label, id} = this.props;
var other = _.omit(this.props, 'label');


To:

const {label, id, ...other} = this.props;


You can notice that we have eliminated the use of lodash/underscore.

You can find more about Babel at their homepage.