ref.current.contains is not a function in React

Viewed 12443

I made a dropdown toggle in React. My dropdown working perfectly fine. But when I try to close the dropdown while clicking outside of the dropdown menu. It shows error. I used ref to find the container element. Sample code


class Search extends React.Component{
    constructor()
    {
        super()
        this.state={
            notificationStatus:false,
            isFocus:false


        }
        this.container=React.createRef()
    }
    toggleNotification=()=>
    {
        this.setState({notificationStatus:!this.state.notificationStatus});
    }

    componentDidMount() {
        document.addEventListener("mousedown", this.handleClickOutside);
      }
      componentWillUnmount() {
        document.removeEventListener("mousedown", this.handleClickOutside);
      }
      handleClickOutside = event => {
          if(this.container.current)
          {
        if (this.container.current && !this.container.current.contains(event.target)) {
          this.setState({
            notificationStatus: false,
          });
        }
    }
      };
    render()
    {
        const {isFocus,notificationStatus}=this.state;
        return(
            <div>
                    <div className="col-md-1 col-sm-1 bell-container flex all-center relative">
                        <img src={bell} onClick={this.toggleNotification} alt="bell icon" />
                    </div>
                {
                    notificationStatus ?  <NotificationList ref={this.container} /> : null
                    
                }
                
            </div>

            
        )
    }
}

2 Answers

Adding a ref on NotificationList component will not give you the reference of the DOM element rendered in it, you need to pass down the ref to the div within NotificationList

<NotificationList innerRef={this.container} />

and in NotificationList

class NotificationList extends React.Component {
   render() {
      <div ref={this.props.innerRef}>{/* */}</div>
   }
}

P.S. a short solution is to use ReactDOM.findDOMNode(this.container.current) but its not longer recommended to use in React

You should remove your nested if at

handleClickOutside

method, just make it correct as follow

      handleClickOutside = event => {
    if (this.container.current && !this.container.current.contains(event.target))               {
      this.setState({
        notificationStatus: false,
      });
    }
}
Related