I have a functional component which i used to detect outside click of the component and once that done i do some logic... now i had to use this inside a class based component
My Hook useComponentVisible
import { useState, useEffect, useRef } from 'react';
export default function useComponentVisible(visible) {
const [isComponentVisible, setIsComponentVisible] = useState(visible);
const ref = useRef(null);
const handleHideDropdown = (event) => {
if (event.key === 'Escape') {
setIsComponentVisible(false);
}
};
const handleClickOutside = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
setIsComponentVisible(false);
}
};
useEffect(() => {
document.addEventListener('keydown', handleHideDropdown, true);
document.addEventListener('click', handleClickOutside, true);
return () => {
document.removeEventListener('keydown', handleHideDropdown, true);
document.removeEventListener('click', handleClickOutside, true);
};
});
return { ref, isComponentVisible, setIsComponentVisible };
}
// How i was using it in my function based component
import useComponentVisible from '../../hooks/useComponentVisible';
import { MenuItem, MenuWrapper } from './MenuDropDownStyle';
const MenuDropDown = () => {
const { ref, isComponentVisible } = useComponentVisible(true);
return (
<>
{isComponentVisible && (
<MenuWrapper ref={ref}>
<MenuItem to="/lectures">Your profile</MenuItem>
<MenuItem to="/lectures">Log out</MenuItem>
</MenuWrapper>
)}
</>
);
};
export default MenuDropDown;
//i need to use the component in CurrencyDropdown
import React, { Component } from "react";
import { SelectWrapper } from "./CurrencyDropdownStyle";
import { getCurrency } from "../../../utls/MakeQuery";
import { SelectInput } from '../../';
import useComponentVisible from '../../hooks/useComponentVisible'
export class CurrencyDropdown extends Component {
constructor() {
super();
this.state = {
currency: [],
};
// const { ref, isComponentVisible } = useComponentVisible(true);
}
componentDidMount() {
getCurrency()
.then((res) => {
this.setState({
currency: res.data.currencies,
});
this.props.toggleCurrency("USD+$");
})
.catch((err) => {
console.log(err);
});
}
// Function That will handle the change of the currency in the state(●'◡'●)
handleToggleCurrency(value){
this.props.toggleCurrency(value)
}
render() {
return <SelectWrapper>
{this.state.currency ? this.state.currency.map((item,index)=>(
<SelectInput key={index} value={`${item.label}+${item.symbol}`} label={`${item.symbol} ${item.label}`}/>
)):""}
</SelectWrapper>;
}
}
export default CurrencyDropdown;
A class-based component cannot use hooks, which are only designed for function-based components.
I'd suggest that you should convert your component to a function-based component or use a wrapper to handle hooks.
Here is how we're using a wrapper to handle your case
class CurrencyDropdownComponent extends Component {
constructor() {
super();
this.state = {
currency: [],
};
// const { ref, isComponentVisible } = useComponentVisible(true);
}
componentDidMount() {
getCurrency()
.then((res) => {
this.setState({
currency: res.data.currencies,
});
this.props.toggleCurrency("USD+$");
})
.catch((err) => {
console.log(err);
});
}
// Function That will handle the change of the currency in the state(●'◡'●)
handleToggleCurrency(value){
this.props.toggleCurrency(value)
}
render() {
return <SelectWrapper>
{this.state.currency ? this.state.currency.map((item,index)=>(
<SelectInput key={index} value={`${item.label}+${item.symbol}`} label={`${item.symbol} ${item.label}`}/>
)):""}
</SelectWrapper>;
}
}
//the function-based component as a wrapper for `CurrencyDropdown` component
function CurrencyDropdown = (props) => {
const { ref, isComponentVisible } = useComponentVisible(true);
return <CurrencyDropdownComponent {...props} isComponentVisible={isComponentVisible} ref={ref}>
}
export default CurrencyDropdown;
Another solution is converting your class-based component to a function-based component
function CurrencyDropdown(props) {
const { ref, isComponentVisible } = useComponentVisible(true);
const [currency, setCurrency] = React.useState([]) //`this.state` replacement
//componentDidMount replacement
useEffect(() => {
getCurrency()
.then((res) => {
setCurrency(res.data.currencies);
props.toggleCurrency("USD+$");
})
.catch((err) => {
console.log(err);
});
}, [])
// Function That will handle the change of the currency in the state(●'◡'●)
handleToggleCurrency(value){
props.toggleCurrency(value)
}
return <SelectWrapper>
{currency ? currency.map((item,index)=>(
<SelectInput key={index} value={`${item.label}+${item.symbol}`} label={`${item.symbol} ${item.label}`}/>
)):""}
</SelectWrapper>
}
export default CurrencyDropdown;