[英]How to check if the element is present in the dom and add some style to another element in dom using react?
我想检查一个元素是否存在于dom中,并使用react为dom中的另一个元素添加样式。 我想做什么? 我有一个弹出窗口和一个按钮显示在同一页面中。 所以当按钮存在时,我想在弹出窗口和按钮之间添加 16px 的空间。 下面是片段,
const Root = () => {
<PopupContextProvider>
<App/>
</PopupContextProvider/>
}
function App() {
return (
<Items/>
<Drawer/>
);
}
function Items() {
const [isOpen, setIsOpen] = React.useState(openByDefault);
const availableItems = 10;
useItemsTrigger(isOpen, availableItems);
}
function Drawer() {
return (
<DrawerButton/> //here is where the DrawerButton is called
);
}
function DrawerButton({ onClick, active, disabled }: Props) {
return (
<ButtonElement //this is the button
onClick={onClick}
data-testid="drawer-button"
/>
);
}
const ButtonElement = styled(IconButton)`
position: fixed;
left: ${-toggleWidthPx - toggleGutterPx}px;
bottom: ${toggleGutterPx}px;
width: ${toggleWidthPx}px;
height: ${toggleWidthPx}px;
padding: 0;
& > svg {
margin: 0;
}
`;
interface ContextProps {
triggerForItems: (availableItems: number) => void;
triggerForProducts: (availableProducts: number) => void;
}
const popupContext = React.createContext<ContextProps>({
triggerForItems: (availableItems: number) => {},
triggerForProducts: (availableProducts: number) => {},
});
const usePopupContext = () => React.useContext(popupContext);
export const PopupContextProvider = ({ children }: any) => {
const [showForItems, setShowForItems] = React.useState(false);
const [showForProducts, setShowForProducts] = React.useState(false);
const dismiss = () => {
if (showForItems) {
sessionStorage.setItem(itemsPopupId, 'dismissed');
setShowForItems(false);
}
if (showForProducts) {
sessionStorage.setItem(mobileUsersPopupId, 'dismissed');
setShowForProducts(false);
}
};
const isDismissed = (dialogId: string) => {
sessionStorage.getItem(dialogId) === 'dismissed';
const context = {
triggerForItems: (availableItems: number) => {
if (!isDismissed(itemsPopupId) && availableItems <= limit) {
setShowForItems(true);
} else if (availableitems > limit) {
setShowForItems(false);
}
},
triggerForProducts: (availableProducts: number) => {
if (!isDismissed(productsPopupId) && availableProducts <= limit) {
setShowForProducts(true);
} else if (availableProducts > limit) {
setShowForProducts(false);
}
},
};
return (
<popupContext.Provider value={context}>
{children}
{(showForSiteShares || showForMobileUsers) && (
<Popup onHide={dismiss} />
)}
</popupContext.Provider>
);
};
export function useProductsTrigger(
enabled: boolean,
availableProducts: number
) {
const { triggerForProducts } = usePopupContext();
React.useEffect(() => {
if (enabled) {
triggerForProducts(availableProducts);
}
}, [enabled, availableProducts, triggerForProducts]);
}
export function useItemsTrigger(
enabled: boolean,
availableItems: number
) {
const { triggerForItems } = usePopupContext();
React.useEffect(() => {
if (enabled) {
triggerForItems(availableItems);
}
}, [enabled, availableItems, triggerForItems]);
export function Popup() { //this is the popup
return (
<Dialog>
<Body>
<span>Title</span>
<Description/>
</Body>
<Actions>
<span> Hide</span>
</Actions>
</Dialog>
);
}
我如何检查按钮(ButtonElement)是否存在于 DOM 中并将左侧边距添加到弹出窗口(对话框)。
我可以将 id 添加到 ButtonElement 并检查该元素是否存在。 但是如果元素存在,我是否向 Popup 添加样式?
我也可以使用 ref 而不是将 id 添加到 ButtonElement 吗? 如果有怎么办?
或者有没有其他更好的方法来做到这一点?
有人可以帮我解决这个问题。 谢谢。
您应该将 state 向上提起。
事实的来源应该存在于您的 state 中,而不是 DOM 中。
由于某些条件而呈现弹出窗口,该条件应存储在 state 中,然后与应用程序的 rest 共享。 您可以使用上下文 API来执行此操作。
然后在您的按钮组件中,您可以查询 state 并相应地调整样式。
所以这个设置应该是这样的:
const PopupContext = createContext()
const App() {
const [popupVisible, setPopoupVisible] = useState(false)
<PopupContext.Provider value={{ popupVisible, setPopupVisible }}>
/* the rest of you application code, any component can set or use the context values */
</PopupContext.Provider>
}
const DrawerButton() {
const { popupVisible } = useContext(PopupContext)
return ... // draw button with customized styles
}
确保当且仅当popupVisible
state 为真时才显示弹出窗口。
编辑(OP更新了问题):
您可以将可见性 state 添加到您的上下文中 -
interface ContextProps {
triggerForItems: (availableItems: number) => void;
triggerForProducts: (availableProducts: number) => void;
isPopupVisible: boolean;
}
const context = {
isPopupVisible: showForItems || showForProducts,
triggerForItems: (availableItems: number) => {
if (!isDismissed(itemsPopupId) && availableItems <= limit) {
setShowForItems(true);
} else if (availableitems > limit) {
setShowForItems(false);
}
},
triggerForProducts: (availableProducts: number) => {
if (!isDismissed(productsPopupId) && availableProducts <= limit) {
setShowForProducts(true);
} else if (availableProducts > limit) {
setShowForProducts(false);
}
},
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.