我有一個功能組件,我用來檢測組件的外部點擊,一旦完成,我就會做一些邏輯......現在我必須在基于類的組件中使用它
我的 Hook 使用ComponentVisible
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 };
}
// 我是如何在基于函式的組件中使用它的
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;
//我需要使用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;
uj5u.com熱心網友回復:
您需要為類組件創建一個包裝器功能組件。
const CurrencyDropdownWrapper = (props) => {
const hookData = useComponentVisible(true);
return <CurrencyDropdown {...props} hookData={hookData} />
}
hookData
然后在你的類組件中使用你的鉤子屬性。
uj5u.com熱心網友回復:
您不能混合使用基于功能和類的組件。您無法在基于類的組件中使用鉤子,它是完全不同的編程反應元素的心理和技術模型。您需要將基于類轉換為功能性(我建議),或者創建另一個類似的useComponentVisible
機制,但采用基于類的樣式。我建議堅持使用基于類或基于函式的風格,當你混合使用這兩種風格時,它會給你帶來麻煩,尤其是當需要在它們之間共享一些功能時。
uj5u.com熱心網友回復:
基于類的組件不能使用掛鉤,掛鉤僅適用于基于函式的組件。
我建議您應該將組件轉換為基于函式的組件或使用包裝器來處理掛鉤。
以下是我們如何使用包裝器來處理您的案例
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;
另一種解決方案是將基于類的組件轉換為基于函式的組件
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;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/496487.html
標籤:javascript 反应 反应钩子 基于反应类的组件
上一篇:如何按名稱反對并分配父級