简体   繁体   中英

this is missing, in react input onChange

In the onChange function I have no this, so no props and no state what am i doing wrong ? thanks

Edit: added class and constructor!

export default class Editor extends Component {
constructor(props) {
    super(props);
    this.state = {
      sortDirection: true,
      json: props.json, // using a prop called json. were setting state.data to json
      options: props.options || {}, //optional object options
      id:props.id,
    }
  }
 onChange = (e) => {
    let xyz=this
    /// this is undefined. needed to set state on controlled input
   }


buildKeys = () => {
    let keys = Object.keys(this.state.json[0]);
    let self = this
    return keys.map((key, index) => {
      // hide column if columname in hidden columns array
      /// if no hidecol option we set it an empty array
      let hiddenColArr = self.state.options.hideCol || []
      // loops throgh hiddenCol array and returns a bool
      let isHidden =  _.includes(hiddenColArr, key) 

     // build values
     let arrIndex=this.props.id -1
     let row = this.state.json[arrIndex];

     return Object.keys(row).map((key2)  =>

     <div key={shortid.generate()} className='row'   >{key}
    ////////////////*Input added here/
        <input  onChange={this.onChange} key={shortid.generate()} type="text" value={row[key2]} />
    /////////////////Input end here/

     </div>

     )

}

When using class notation (your only choice as of React 16), you need to use arrow functions, ie <Thing onChange={() => this.onChange()} .../> . in order to preserve this .

If you don't, by the time onChange fires, the execution context for that call is guaranteed to not be your component, and is most likely just window .

You'll also want to change those instance properties to normal class functions:

class Thing extends Component {
  constructor(props) {
    super(props);
    this.state = ...
  }

  onChange(evt) {
    // do what needs to be done
  }

  render() {
    return <div ... >
      <input onChange={evt => this.onChange(evt)} ... />
    </div>;
  }
}

In fact, if you're using Babel + Webpack, I can almost guarantee you that's already what Babel will do to your code, so the code that runs will have normal class functions, and so you really need that arrow function as onChange handler.

(some tutorials advocate putting this.onChange = this.onChange.bind(this) in your constructor, which I would not recommend you do. It's not your constructor's job to known what the rest of the class looks like)

You can bind this to your functions by binding it in your constructor:

...
constructor(props){
    super(props);
    this.onChange = this.onchange.bind(this);
}
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM