Manus Gallagher
Manus Gallagher

Reputation: 1043

ReactJS onChange function

Where am I going wrong with my onChange function? I want to be able to type in my textbox, but I keep getting the following console error when I recompile:

**Uncaught TypeError: Cannot read property 'value' of undefined**

See code below:

var name = "";
export default React.createClass({

  handleChange: function() {
    this.props.onUserInput(
        this.refs.name.value    
    )
  },

  render() {
    return (
      <div>
        <div>{this.props.children}</div>
        <Well style={style.well}>
          <div style={style.userContent}>

            <input style={style.userDetails} 
                   id ="userName" 
                   type="text" 
                   onChange={this.handleChange()} 
                   value ={name} />

              <Button bsStyle="primary">Update</Button>
          </div>
        </Well>         
      </div>
    );
  }
});

Upvotes: 0

Views: 18416

Answers (2)

Oleksandr T.
Oleksandr T.

Reputation: 77522

Remove ()., to onChange you have to pass reference to function

onChange={ this.handleChange } 

Update:

Also, in this case, you don't need refs, because you can get value like so

handleChange: function (event) {
  this.props.onUserInput(
    event.currentTarget.value    
  )
},

Based on your example, I see that you use variable name, it is bad practice, I think in this case you can use state, like in my example

const App = React.createClass({
  getInitialState: function () {
    return {
      value: ''
    }
  },
  
  handleChange: function (event) {
    this.setState({
      value: event.currentTarget.value
    }, () => { // arrow function, ES2015
      console.log(this.state.value);
      // call this.props.onUserInput(this.state.value)
    });
  },

  render() {
    return (
      <input style={ {} } 
        id="userName" 
        type="text" 
        onChange={ this.handleChange } 
        value={ this.state.value } 
      />
    );
  }
});

ReactDOM.render(<App />, document.getElementById('root'))
<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="root"></div>

Upvotes: 3

salezica
salezica

Reputation: 77129

Well, two things are going on.

First, this.refs.name is undefined, and you can't read the property value of undefined (as the error says). You never created the ref in your render() method. Read the React docs on the ref attribute to better understand how it works, and the inherent limitations.

Second, you're invoking the handleChange function instead of just passing it as onChange:

onChange={this.handleChange()} // you CALL the function with ()

Instead, pass it directly:

onChange={this.handleChange}

Note that if you switch to ES6 class components, you'll also need to bind the function (otherwise this will be undefined when handleChange runs):

onChange={this.handleChange.bind(this)}

For now, React.createClass is doing the binding for you.

Upvotes: 0

Related Questions