#javascript #css #reactjs #sass #styled-components
#javascript #css #reactjs #sass #styled-components
Вопрос:
Я пытаюсь условно отобразить состояние / вид наведения в стилизованных компонентах, используя реквизиты, поступающие из react…
В настоящее время мой код выглядит примерно так:
${isHovered}, amp;:hover {
background: red;
}
К сожалению, это не помогает иметь значение true / false, поскольку я упускаю что-то, что, как я полагаю, может выполнять либо / либо псевдо..
Я хочу иметь возможность явно показывать состояние наведения при сохранении псевдонаведения по умолчанию. Как я могу этого добиться?
Комментарии:
1. Не элегантно, но должно работать
background: ${props => props.isHovered ? 'red': 'inherit'}; amp;:hover { background: red}
2. @YuryTarabanko ах, это действительно работает, но вызывает МНОГО дублирования кода.. было бы неплохо иметь что-то такое же простое, как
variable, amp;:hover
для того, чтобы охватить оба экземпляра: (
Ответ №1:
То, как у вас есть ваши селекторы прямо сейчас, недопустимо:
Проблема
${isHovered}, amp;:hover {
background: red;
}
На данный момент это всегда будет переводиться в:
undefined, amp;:hover {
background: red;
}
Для простоты, чтобы правильно интерполировать, это должна быть функция, принимающая props
, которая возвращает string
:
color: ${props => props.isHovered amp;amp; "pink" };
В связи с этим, даже если вы обернули свой стилизованный компонент в компонент более высокого порядка, где isHovered
определяется как аргумент, он, к сожалению, все равно не будет работать в рабочей среде для styled-components v5 — это работало в v4, но v5.x не обрабатывает должным образом css-интерполяции в стилизованном компоненте при компиляции дляпроизводство (см. Отслеживание проблем здесь).
Решения
Лучшим и рекомендуемым подходом было бы интерполировать внутри свойства CSS:
background: ${({ isHovered }) => isHovered amp;amp; "red"};
:hover {
background: red;
}
В качестве альтернативы, если у вас есть несколько правил CSS, вы можете выполнять интерполяцию вне свойства CSS:
${({ isHovered }) => isHovered amp;amp; "background: red;color: white;"};
:hover {
background: red;
}
Теперь вы просто передаете свой компонент в isHovered
prop.
<StyledComponent isHovered={isHovered} />
Хотя технически вы можете это сделать (обратите внимание, что значения falsey приравниваются к true, что может быть ошибкой или необработанным краевым случаем)…
${({ isHovered }) => !isHovered amp;amp; ".hovered"}, amp;:hover {
background: red;
}
… это НЕ рекомендуется из-за того, как это интерпретируется:
".hovered", amp;:hover {
background: red;
}
Возможно, это не то, что вы хотели бы, потому .hovered
что оно вообще не используется в DOM, что может сбить с толку других разработчиков. Вместо этого он повторно использует скомпилированное имя хэшированного класса для добавления свойства CSS в другое правило (сосредоточьтесь на Styles
вкладке, чтобы увидеть разницу):
скриншот
В то время как рекомендуемый подход устанавливает свойство CSS для хэшированного класса в том же блоке правил: скриншот
Рабочая демонстрация (эта демонстрация включает оба примера кода выше, где Title
используется рекомендуемый подход и SubTitle
нет):
Комментарии:
1. Спасибо за исчерпывающее объяснение, ценю это!
Ответ №2:
import styled, { css } from 'styled-components';
const getHoverStyle = (props) => {
if(props?.isHovered) {
return (
css`
amp;:hover {
background: red;
}
`
)
}
}
export const SomeName = styled.div`
${getHoverStyle}
`;
Комментарии:
1. Проверка наведена в props, как props? .Завис. Спасибо
Ответ №3:
Вы можете использовать class
селектор для применения стиля, а в вашем стилизованном компоненте вы можете использовать attr
call для установки className
атрибута на основе значения свойства, например:
const MyComp = styled.div.attrs((props) => ({
className: props.isHovered ? "hovered" : ""
}))`
color: ${(props) => props.color};
amp;.hovered,
amp;:hover {
color: blue;
}
`;
Взгляните на эту песочницу react.
Комментарии:
1. @BryceSnyder это то, что вы ищете?
Ответ №4:
Я создал интерактивную игровую площадку. Вы можете перейти по ссылке ниже. Это может вам помочь.
https://codesandbox.io/s/focused-sky-vp8d9?file=/src/App.js
Ниже приведен код.
import React, { useState } from "react";
import "./styles.css";
import styled, { css } from "styled-components";
const HoverExample = styled.div`
background: pink;
width: 100%;
min-height: 80px;
${(props) =>
props.isHovered amp;amp;
css`
amp;:hover {
background: green;
}
`}
`;
export default function App() {
const [isHovered, setisHovered] = useState(false);
return (
<div className="App">
<button onClick={() => setisHovered(!isHovered)}>
{!isHovered ? "Enable" : "disabled"} Hover
</button>
<p>Hover is {isHovered ? "enabled" : "disabled"}</p>
<HoverExample isHovered={isHovered}></HoverExample>
</div>
);
}
Спасибо.