To make more composable React components, you can define common APIs for similar component types.
import React from 'react'; import ReactDOM from 'react-dom'; export default class App extends React.Component{ constructor(){ super(); this.state = { red: 0, green: 0, } } update(){ this.setState({ red: ReactDOM.findDOMNode(this.refs.red.refs.inp).value, green: ReactDOM.findDOMNode(this.refs.green.refs.inp).value, }) } render(){ return( <div> <NumInput ref="red" type="range" min={0} max={255} step={1} val={+this.state.red} label="Red" update={this.update.bind(this)} ></NumInput> <NumInput ref="green" type="number" step={0.01} val={+this.state.green} label="Green" update={this.update.bind(this)} ></NumInput> </div> ); } } class NumInput extends React.Component{ constructor(){ super(); } render() { const label = this.props.label ? <label>{this.props.label} - {this.props.val}</label> : ''; return ( <div> <input type={this.props.type} min={this.props.min} max={this.props.max} step={this.props.step} defaultValue={this.props.val} onChange={this.props.update} ref="inp" /> {label} </div> ); } } NumInput.propTypes = { type: React.PropTypes.oneOf(['range', 'number']), min: React.PropTypes.number, max: React.PropTypes.number, step: React.PropTypes.number, val: React.PropTypes.number, label: React.PropTypes.string, update: React.PropTypes.func.isRequired, }; NumInput.defaultProps = { type: 'range', min: 0, max: 255, step: 1, val: 0, label: '' };