#reactjs #styled-components
#reactjs #компоненты в стиле
Вопрос:
У меня есть простое приложение React, которое получает CSS из внешнего источника в форме JSON, стили выглядят так:
{
"DOMElements": [
{
"padding": "1rem",
"margin": "5rem",
},
{
"boxSizing": "border-box",
"height": "10px",
}
]
}
Поэтому, когда я получаю ответ, подобный приведенному выше, я хочу получить что-то вроде этого:
import styled from 'styled-components';
const DOMElement1 = styled.div`
padding: 1rem,
margin: 5rem,
`;
const DOMElement2 = styled.div`
boxSizing: border-box,
height: 10px,
`;
const Page = ({ children }) => (
<>
<DOMElement1>{children[1]}</DOMElement1>
<DOMElement2>{childrem[2]}</DOMElement2>
</>
);
Стоит отметить, что количество DOMElements в unknown может быть 1, может быть 50.
Составная часть проста, я могу просто делать indexed map
и увеличивать индекс в каждом цикле. Проблема, с которой я сталкиваюсь, заключается в том, как мне создать динамические компоненты в стиле компонентов на основе ответа JSON? Мне нужно сделать это внутри самого компонента, поскольку я знаю, как DOMElements
он выглядит, но styled-components должны находиться вне функции компонента… Чего мне не хватает? Это вообще выполнимо?
Ответ №1:
Вы можете предоставить реквизиты для стилизованных компонентов.
const DOMElement1 = styled.div`
padding: ${({padding}) => padding}rem,
margin: ${({margin}) => margin}rem,
`;
const Page = ({ children }) => (
<>
<DOMElement1 padding={valueFromJson} margin={valueFromJson}>{children[1]}</DOMElement1>
<DOMElement2 padding={valueFromJson} margin={valueFromJson}>{childrem[2]}</DOMElement2>
</>
);
Комментарии:
1. Я знаю об этом, проблема в том, что у меня не будет двух элементов DOM, их количество будет динамическим / неизвестным, это был просто пример. Я бы использовал
children.map
вместо жесткого кодированияDOMElements
, как в приведенном выше коде.
Ответ №2:
Что-то вроде этого:
const items = [
{
background: "blue",
width: "30px",
height: "30px",
padding:'10px'
},
{
height: "40px",
background: "red",
width: "30px",
padding:'10px'
}
];
const components = items.map((item) =>
styled("div")({
...item
})
);
export default function App() {
return (
<div style={{ background: "lightblue", width: "100vw", height: "100vh" }}>
{components.map(Comp => <Comp>hi</Comp>)}
</div>
);
}
Комментарии:
1.
items
будут отправлены в качестве реквизитаApp
, поэтому я не могу получить к ним доступ за пределамиApp
компонента: [2. Вы можете сделать это внутри:
return items.map((item) => styled("div")({ ...item }) ).map(C => <C />) }
Ответ №3:
Простым и понятным решением было бы динамически использовать реквизит в вашем стилизованном компоненте, и таким образом вам не нужно беспокоиться о каком-либо входящем свойстве css.
Обратитесь к следующему примеру / этому фрагменту —
const DOMElement = styled.div`
${props => props}
`;
const Page = () => {
const data = {
"DOMElements": [
{
"padding": "1rem",
"margin": "5rem",
},
{
"boxSizing": "border-box",
"height": "10px",
}
]
};
return (
<>
{data?.DOMElements?.map((obj, index) =>
<DOMElement {...obj} key={index}>abcd</DOMElement>
)}
</>
);
}