#reactjs #styled-components
#reactjs #компоненты в стиле
Вопрос:
Как мне заставить это работать?
img
передается как <Child />
реквизит, и я хочу изменить фоновое изображение дочернего элемента при <Parent />
наведении курсора
<Parent>
<Child img={'path/to/img.png'}/>
</Parent>
const Child = styled.div`
`;
const Parent = styled.div`
amp;:hover {
${Child} {
background-image: url(${props => props.img});
}
}
`;
Комментарии:
1. Я думаю, это потому, что ‘img’ передается дочернему элементу вместо родительского, но вы обращаетесь к нему внутри родительского элемента.
2. Как сказал хаопенг, в этом случае
props
содержит реквизитыParent
компонента, а не реквизитыChild
компонента. Вам нужно достичь своей цели только с помощьюstyled-component
или вы можете использовать какой-то обходной путь с помощью JS? РЕДАКТИРОВАТЬ: было бы полезно узнать,Child
всегда ли будет единственным дочерним элементомParent
; если да, я могу показать вам решение, использующее только styled-component
Ответ №1:
Надеюсь, это может вам помочь!
amp;:hover ${Child}{
background-image: url(${props => props.image amp;amp; css`${props.image}`});
}
Вот рабочий пример https://codepen.io/hardik-chaudhary/pen/rKEKWG
ОБНОВЛЕННЫЙ КОД
Используйте код наведения в дочернем элементе вместо родительского. И все просто отлично работает. Я также обновил код в ручке (https://codepen.io/hardik-chaudhary/pen/rKEKWG ).
const Child = styled.div`
${Parent}:hover amp; {
background-image: url(${props => props.image amp;amp; css`${props.image}`});
}
`;
Комментарии:
1. это работает, потому что вы передаете
image
в<Button />
, что, если я захочуimage
передать в<Child />
, я не хочу<Child />
использовать реквизиты его родителя, это делает код уродливым.2. Я обновил код в данном pen. Вы можете передать реквизит от дочернего элемента и можете изменить фон при наведении курсора мыши.
Ответ №2:
Итак, мне удалось частично решить проблему (возможно, то, что осталось, в вашем случае не важно, дайте мне знать).
Сначала скрипка, затем пояснения:
const img1 = "https://images.pexels.com/photos/2047905/pexels-photo-2047905.jpeg?cs=srgbamp;dl=apple-device-art-colorful-2047905.jpgamp;fm=jpg";
const img2 = "https://images.pexels.com/photos/2027104/pexels-photo-2027104.jpeg?auto=compressamp;cs=tinysrgbamp;dpr=2amp;h=650amp;w=940";
const img3 = "https://images.pexels.com/photos/2029478/pexels-photo-2029478.jpeg?auto=compressamp;cs=tinysrgbamp;dpr=2amp;h=650amp;w=940";
window.styled = window.styled.default;
function changeBG(props) {
if (Array.isArray(props.children)) {
let a;
props.children.forEach(el => {
if (el.type.styledComponentId === Child.styledComponentId) {
a = el.props.bgImg;
}
});
return a;
} else {
return (props.children.type.styledComponentId === Child.styledComponentId)
? props.children.props.bgImg
: ""
}
}
const Child = styled.div`
width: 200px;
height: 100px;
border: 1px solid green;
background-image: url("${img2}");
background-size: contain;
`;
const Parent = styled.div`
width: 400px;
height: 200px;
border: 1px solid rgba(0,0,0,0.5);
amp;:hover {
${Child} {
background-image: url("${props => changeBG(props)}");
}
}
`;
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Parent>
<Child bgImg={img1} />
<Child bgImg={img3} />
</Parent>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
const img1 = "https://images.pexels.com/photos/2047905/pexels-photo-2047905.jpeg?cs=srgbamp;dl=apple-device-art-colorful-2047905.jpgamp;fm=jpg";
const img2 = "https://images.pexels.com/photos/2027104/pexels-photo-2027104.jpeg?auto=compressamp;cs=tinysrgbamp;dpr=2amp;h=650amp;w=940";
const img3 = "https://images.pexels.com/photos/2029478/pexels-photo-2029478.jpeg?auto=compressamp;cs=tinysrgbamp;dpr=2amp;h=650amp;w=940";
window.styled = window.styled.defau<
function changeBG(props) {
console.log(props.children);
if (Array.isArray(props.children)) {
let a;
props.children.forEach(el => {
if (el.type.styledComponentId === Child.styledComponentId) {
a = el.props.bgImg;
}
});
return a;
} else {
return (props.children.type.styledComponentId === Child.styledComponentId)
? props.children.props.bgImg
: ""
}
}
const Child = styled.div`
width: 200px;
height: 100px;
border: 1px solid green;
background-image: url("${img2}");
background-size: contain;
`;
const Parent = styled.div`
width: 400px;
height: 200px;
border: 1px solid rgba(0,0,0,0.5);
amp;:hover {
${Child} {
background-image: url("${props => changeBG(props)}");
}
}
`;
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Parent>
<Child bgImg={img1} />
<Child bgImg={img3} />
</Parent>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/styled-components/3.4.10/styled-components.min.js"></script>
<div id='root'></div>
В принципе, Parent
styled-component действует так, как вы написали, ожидайте, что он запускает вызываемую функцию changeBG
. При этом, проверяя el.type.styledComponentId === Child.styledComponentId
, я проверяю, что дочерний элемент имеет тип Child
: если это так, мы можем использовать props.bgImg
.
Хотя, может возникнуть некоторая проблема, если у Parent
компонента есть дочерние элементы, которые не являются Child
типом.. И, если дочерних Child
компонентов несколько Parent
, я все еще не смог отобразить другое фоновое изображение при наведении курсора мыши.. Но, я спрашиваю, это необходимо? Я могу попытаться найти обходной путь и для этого.