У меня есть несколько аккордеонных компонентов, созданных с использованием методологии составных компонентов (Райан Флоренс рассказывает о составных компонентах здесь ).
Одно из правил ESLint, которое я настроилis import / no-cycle , чтобы предотвратить круги зависимости.Поскольку я использую методологию составного компонента, а также рекомендованный способ ссылаться на другие компоненты в Стилизованных компонентах, сохраняя все стили, относящиеся к конкретному компоненту в этом файле, я запускаю импорт / нетпредупреждение о цикле.
Вот мой файл Accordion.js.
import React, { useState } from "react";
import AccordionTrigger from "./accordionTrigger";
import AccordionContent from "./accordionContent";
const Accordion = ({ children, show }) => {
const [isActive, setIsActive] = useState(show);
const handleTriggerClick = () => {
setIsActive(!isActive);
};
const compoundChildren = React.Children.map(children, child => {
switch (child.type) {
case AccordionTrigger:
return React.cloneElement(child, {
onClick: handleTriggerClick,
active: isActive ? 1 : 0,
});
case AccordionContent:
return React.cloneElement(child, {
show: isActive,
});
default:
return child;
}
});
return <div show={show ? 1 : 0}>{compoundChildren}</div>;
};
export default Accordion;
И мой файл AccordionTrigger.js.
import React from "react";
import styled from "styled-components";
import FauxButton from "../buttons/fauxButton";
import Accordion from "./accordion";
import TopLevelTrigger from "./topLevelTrigger";
import SecondaryLevelTrigger from "./secondaryLevelTrigger";
const Root = styled(FauxButton)`
${Accordion} & {
width: 100%;
border-bottom: 1px solid ${p => p.theme.greyLight};
}
`;
const AccordionTrigger = ({ active, children, ...rest }) => {
const clonedChildren = React.Children.map(children, child => {
switch (child.type) {
case TopLevelTrigger:
case SecondaryLevelTrigger:
return React.cloneElement(child, {
active,
});
default:
return child;
}
});
return <Root {...rest}>{clonedChildren}</Root>;
};
export default AccordionTrigger;
Одна вещь, которую я попробовал, это определениестили AccordionTrigger
в Accordion.js
примерно так ...
const Root = styled.div`
${AccordionTrigger} & {
width: 100%;
border-bottom: 1px solid ${p => p.theme.greyLight};
}
`;
const Accordion = ({ children, show }) => {
...same logic as before here
return <Root show={show ? 1 : 0}>{compoundChildren}</Root>;
};
... но это не работает, стили просто не добавляются в компонент AccordionTrigger
.Я знаю, что могу просто добавить свой собственный класс с помощью className
prop при клонировании внутри компонента Accordion
и затем обращаться к нему таким образом, но мне было интересно, есть ли способ предотвратить это?