简体   繁体   中英

ref does not work in this reactjs component

I want to change the css class of a span element whenever an anchor is clicked

I will modify the css class in the onclick callback

class Button extends Component {
  handleCallback() {
    this.icon.className = this.icon.className + ' wiggle'
  }
  render() {
    return (
      <div>
        <span className='highlight'>{this.props.summary}</span>
        <a  
          className='link'
          onClick={this.handleCallback}
        >   
          <span ref={(c) => this.icon = c} className='icon-up'></span>
        </a>

      </div>
    );  
  }
}

To do so I need to be able to refer the component. That's why I use the ref attribute in the span class.

However when the callback is called, I got this error:

Uncaught TypeError: Cannot read property 'icon' of null

Why the ref does not work here?

You're missing a few things here

First off, you're writing an ES6 component class and when using ES6 together with React, React no longer features auto binding of this making your call to handleCallback refer to a this which will be null.

this.handleCallback.bind(this) or declare your callback with an arrow function handleCallback = () => {} will take care of that problem.

And secondly, the way you're trying to set the className is not allowed, React only updates the tree (ie, what you see) when re-rendering and React will never flush the changes you made 'inline' back into the DOM so you would have to utilize this.setState() or this.forceUpdate() in order to be able to see, but since your changes are inline they will never persist on a subsequent render.

Below is a very verbose Component to illustrate how to do it

class Button extends React.Component {
  constructor() {
    super();
    this.state = {
      shouldWiggle: false
    };
  }
  handleCallback() {
    this.setState({shouldWiggle: !this.state.shouldWiggle});
  }
  render() {
    let cls = this.state.shouldWiggle ? 'icon-up wiggle': 'icon-up';
    return (
      <div>
        <span className='highlight'>{this.props.summary}</span>
        <a  
          className='link'
          onClick={this.handleCallback.bind(this)}
        >   
          <span ref={(c) => this.icon = c} className={cls}>ad</span>
        </a>

      </div>
    );  
  }
}

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