Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
37
rated 0 times [  43] [ 6]  / answers: 1 / hits: 16450  / 4 Years ago, wed, december 16, 2020, 12:00:00

I am trying to build a dropdown menu. The base structure Test is where I need to detect clicks outside the content area using React ref and styled-components.


I have checked the related articles in SO but they use hooks not supported on my class component.


Here is the code:


import React from "react";
import PropTypes from "prop-types";
import styled, { ThemeProvider } from "styled-components";

import { theme } from "../theme";

import Icon from "../Icon";

const Container = styled.div`
display: flex;
`};

const SelectorDiv = styled.div`
background-color: black;
color: white;
height: 100px;
`;

class Test extends React.Component {
componentDidMount () {
document.addEventListener("mousedown", this.handleClickOutside);
}

componentWillUnmount () {
document.removeEventListener("mousedown", this.handleClickOutside);
}

handleClickOutside = event => {
console.log(this.refs); // undefined
}


handleClickInside = () => {
alert("Clicked inside");
}

render = () => {

return (
<ThemeProvider theme={theme}>
<Container disabled={disabled}>
<SelectorDiv
onClick={this.handleClickInside}
ref={"wrapper"}
>
<h1>This is the content to click</h1>
</SelectorDiv>
</Container>
</ThemeProvider>
);
};
}
export default Test;

The ref is not working property. When clicking outside the are I'm getting undefined on this.refs. Seens that styled-components had issues with this, but it was solved on V4 (I'm using V5.1.0).


How to get the wrapper component inside my handleOutsideClick?


More From » reactjs

 Answers
75

Using ref as a string as you tried is a legacy way of React older API.

And they don't recommended using that:



If you worked with React before, you might be familiar with an older API where the ref attribute is a string, like "textInput", and the DOM node is accessed as this.refs.textInput. We advise against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases.


Note: If you’re currently using this.refs.textInput to access refs, we
recommend using either the callback pattern or the createRef API
instead.



use React.createRef() instead,
And you can access it with current attribute of the ref variable like so:





class Test extends React.Component {
constructor() {
super(props);

this.selectorRef = React.createRef(null);
}

componentDidMount() {
document.addEventListener("mousedown", this.handleClickOutside);
}

componentWillUnmount() {
document.removeEventListener("mousedown", this.handleClickOutside);
}

handleClickOutside = event => {
console.log(this.selectorRef.current);
}


handleClickInside = () => {
alert("Clicked inside")
}

render = () => {

return (
<ThemeProvider theme={theme}>
<Container disabled={disabled}>
<SelectorDiv
onClick={this.handleClickInside}
ref={selectorRef}
>
<h1>This is the content to click</h1>
</SelectorDiv>
</Container>
</ThemeProvider>
);
};
}
export default Test;

Check it on sandBox


In functional components you can use React hook useRef()


Refs and the Dom

useRef


[#50484] Tuesday, December 1, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
jenamackennac

Total Points: 304
Total Questions: 110
Total Answers: 107

Location: Ecuador
Member since Thu, Jun 4, 2020
4 Years ago
jenamackennac questions
Fri, Feb 18, 22, 00:00, 2 Years ago
Wed, Apr 21, 21, 00:00, 3 Years ago
Thu, Apr 1, 21, 00:00, 3 Years ago
Tue, Feb 2, 21, 00:00, 3 Years ago
;