16

I currently have this simple react app and I cannot get these onchange events to fire for the life of me.

var BlogForm = React.createClass({
getInitialState: function() {
    return {
        title: '',
        content: ''
    };
},
changeTitle: function(event) {

    var text = event.target.value;

    console.log(text);

    this.setState({
        title: event.target.value
    });
},
changeContent: function(event) {
    this.setState({
        content: event.target.value
     });
},
addBlog: function(ev) {
    console.log("hit hit");
},
render: function() {
    return (
                <form onSubmit={this.addBlog(this)}>
                    <div>
                        <label htmlFor='picure'>Picture</label>
                        <div><input type='file' id='picture' value={this.state.picture} /></div>
                    </div>
                    <div>
                        <input className="form-control" type='text' id='content' value={this.state.title} onChange={this.changeTitle} placeholder='Title' />
                    </div>
                    <div>
                        <input className="form-control" type='text' id='content' value={this.state.content} onChange={this.changeContent} placeholder='Content' />
                    </div>
                    <div>
                        <button className="btn btn-default">Add Blog</button>
                    </div>
                </form>

    );
  }
});

Funny thing is when I use onChange={this.changeTitle (this)}, the event fires but the ev variable in the changeTitle function is not the correct one.

Zoe
  • 27,060
  • 21
  • 118
  • 148

5 Answers5

23

Try:

onChange={(evt) => this.changeTitle(evt)}

or:

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

instead of:

onChange={this.changeTitle}
radiovisual
  • 6,298
  • 1
  • 26
  • 41
Samuli Hakoniemi
  • 18,740
  • 1
  • 61
  • 74
  • onChange={(evt) => props.onChangeDate(evt)} using this paradigm: https://facebook.github.io/flux/docs/flux-utils.html – Chuck Han Mar 23 '17 at 05:40
  • 14
    If the function is bound correctly... why would all 3 of these not work? – Dmitry Minkovsky May 23 '17 at 15:04
  • 1
    Please explain why the top one does work and the bottom one does not – Mazzy Aug 21 '17 at 14:01
  • I know this is an old response, but you should never do the first two examples. It creates a major performance hit as it will create a done of additional renders. You should always use the third form. – samanime Jan 08 '20 at 15:58
4

try moving the onChange to the parent div.. this worked for me

Chris
  • 425
  • 3
  • 12
  • 1
    This works fine. But do you know why it works? Because many examples show that onChange should be put in the component or input you are calling. – nucky Apr 23 '21 at 15:22
1

The accepted answer is correct, BUT I wanted to add that, if you are implementing the radio group button solution as provided in the bootstrap documentation, make sure to remove the "data-toggle" option on the surrounding div:

<div class="btn-group btn-group-toggle" data-toggle="buttons">
  <label class="btn btn-secondary active">
    <input type="radio" name="options" id="option1" autocomplete="off" checked> Active
  </label>
</div>

If you keep the data-toggle option as shown in the code above, the onClick and onChange events you added yourself to the input field will be ignored.

Jenever
  • 500
  • 5
  • 17
0

when you use :

onChange={this.changeTitle (this)}

react will call mentioned function automatically. you need to call the function like this:

onChange={this.changeTitle}

and also change your mentioned function to arrow function, otherwise you cant use "this" keyword in your function. in none arrow function "this" keyword is not object of your function so you cant access to your variables. if you need to pass arguments to your function you should use other methods like bind()

0

Make sure you're not giving it an already given id. I'm not really why, but having duplicate ids for input with type file stops it from working.

Boz
  • 163
  • 2
  • 12