Using refs
is not best practice because it reads the DOM directly, it’s better to use React’s state
instead. Also, your button doesn’t change because the component is not re-rendered and stays in its initial state.
You can use setState
together with an onChange
event listener to render the component again every time the input field changes:
// Input field listens to change, updates React's state and re-renders the component. <input onChange={e => this.setState({ value: e.target.value })} value={this.state.value} /> // Button is disabled when input state is empty. <button disabled={!this.state.value} />
Here’s a working example:
class AddItem extends React.Component { constructor() { super(); this.state = { value: '' }; this.onChange = this.onChange.bind(this); this.add = this.add.bind(this); } add() { this.props.onButtonClick(this.state.value); this.setState({ value: '' }); } onChange(e) { this.setState({ value: e.target.value }); } render() { return ( <div className="add-item"> <input type="text" className="add-item__input" value={this.state.value} onChange={this.onChange} placeholder={this.props.placeholder} /> <button disabled={!this.state.value} className="add-item__button" onClick={this.add} > Add </button> </div> ); } } ReactDOM.render( <AddItem placeholder="Value" onButtonClick={v => console.log(v)} />, document.getElementById('View') );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id='View'></div>