简体   繁体   中英

React - Can't access refs in stateful component event handler

I have a class component that has a onClick event handler that references an inner ref input . However, in the event handler input is null. I am binding the event handler to this in constructor.

import React, { Component} from 'react';

class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this);
  }

  onClick(e) {
    // The following throws "Cannot read property 'click' of undefined"
    this.input.click();
  }

  render() {
    return (
      <div className="container" onClick={this.onClick}>
        <input type="text" ref={input => this.input = input} />
      </div>
    );
  }
}

Why is this.input undefined in my event handler?

EDIT Apparently the code runs fine, just not in my environment. I am using webpack and babel with the env and react presets w/ hot reloading. I am targeting electron .

Full error stack:

my-component.jsx:12 Uncaught TypeError: Cannot read property 'click' of undefined
    at MyComponent.onClick (http://localhost:8080/renderer.js:19224:15)
    at Object.ReactErrorUtils.invokeGuardedCallback (webpack:///./node_modules/react-dom/lib/ReactErrorUtils.js?:69:16)
    at executeDispatch (webpack:///./node_modules/react-dom/lib/EventPluginUtils.js?:85:21)
    at Object.executeDispatchesInOrder (webpack:///./node_modules/react-dom/lib/EventPluginUtils.js?:108:5)
    at executeDispatchesAndRelease (webpack:///./node_modules/react-dom/lib/EventPluginHub.js?:43:22)
    at executeDispatchesAndReleaseTopLevel (webpack:///./node_modules/react-dom/lib/EventPluginHub.js?:54:10)
    at Array.forEach (native)
    at forEachAccumulated (webpack:///./node_modules/react-dom/lib/forEachAccumulated.js?:24:9)
    at Object.processEventQueue (webpack:///./node_modules/react-dom/lib/EventPluginHub.js?:254:7)
    at runEventQueueInBatch (webpack:///./node_modules/react-dom/lib/ReactEventEmitterMixin.js?:17:18)

EDIT

Figured it out see my answer below.

Figured it out, it was a problem with react-hot-loader . Apparently saving the value of this doesn't work in the constructor with react-hot-loader . The fix is to manually enable the transform-es2015-classes plugin in your babelrc.

See https://github.com/gaearon/react-hot-loader/issues/597

I think you are trying to get input value. if yes here is the code. There is no this.input.click(); method definition

import React from 'react';

class MyComponent extends React.Component {
   constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this);
  }

  onClick(e) {
    // The following throws "Cannot read property 'click' of undefined"
    console.log(this.input.value);
  }

  render() {
    return (
      <div className="container">
        <input type="text" ref={input => this.input = input} onChange={this.onClick}/>
      </div>
    );
  }
}

export default MyComponent;

Have you tried rewriting your onClick callback as an arrow function? This will also make your code a little smaller:

import React, { Component } from 'react';

class MyComponent extends Component {
  this.input = null;

  onClick = () => {
    this.input && this.input.click();
  }

  render() {
    return (
      <div className="container" onClick={this.onClick}>
        <input type="text" ref={input => this.input = input} />
      </div>
    );
  }
}

Even though it shouldn't matter, I also check if this.input is set - but you can ignore that part (usually).

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