-
TIL-2024.05.07 - React - 013. Styled Component - basic- 2> Frontend/React 2024. 5. 8. 07:07
1. Coming From CSS
1.1. Pseudoelements, pseudoselectors, and nesting
- 사용하는 전처리기인 stylis는 자동으로 스타일을 중첩하는 SCSS와 유사한 구문을 지원합니다.
- 이 전처리를 통해 styled-components는 일부 고급 선택자 패턴을 지원합니다:
- & 단일 앰퍼샌드는 컴포넌트의 모든 인스턴스를 가리킵니다. 이것은 넓은 범위의 재정의에 사용됩니다.
1.1.1 단일 엠퍼센드 (&)
- & 단일 앰퍼샌드는 컴포넌트의 모든 인스턴스를 가리킵니다. 이것은 넓은 범위의 재정의에 사용됩니다.
예제
import styled from "styled-components"; // single ampersand (&) refers to all instances of the component; it is used for applying broad overrides: const SingleAmpersand = () => { const Thing = styled.div.attrs((/* props */) => ({tabIndex: 0}))` color: blue; &:hover { // <Thing> when hovered // Pretty nice day today 제외 전체 color: red; } & ~ & { // <Thing> as a sibling of <Thing>, but maybe not directly next to it // Dont' you think 에 해당 background: tomato; } & + & { // <Thing> next to <Thing> // How ya doing 에 해당 background: lime; } &.something { // <Thing> tagged with an additional CSS class ".something" // The Sun is Shining... 에 해당 background: orange; } .something-else & { // <Thing> inside another element labeled ".something-else" // splendid에 해당 border: 1px solid; background: white; } `; return ( <div> <Thing>Hello world!</Thing> <Thing>How ya doing?</Thing> <Thing className="something">The sun is shining...</Thing> <div>Pretty nice day today.</div> <Thing>Don't you think?</Thing> <div className="something-else"> <Thing>Splendid.</Thing> </div> </div> ); }; export default SingleAmpersand;
1.1.2 더블 엠퍼센드(&&)
- && 두 개의 앰퍼샌드는 컴포넌트의 인스턴스를 가리킵니다.
- 이것은 조건부 스타일 재정의를 수행하고 특정 컴포넌트의 모든 인스턴스에 스타일이 적용되지 않도록 하는 데 유용합니다.
예제
import styled, {css} from "styled-components"; // double ampersand refers to an instance of the component; // this is useful if you're doing conditional styling overrides and don't want a style to apply to all instances of a particular component: const DoubleAmpersand = () => { const Input = styled.input.attrs({type: "checkbox"})``; const Label = styled.label` align-items: center; display: flex; gap: 8px; margin-bottom: 8px; `; const LabelText = styled.span` ${(props) => { switch (props.$mode) { case "dark": return css` background-color: black; color: white; ${Input}:checked + && { color: blue; } `; default: return css` background-color: white; color: black; ${Input}:checked + && { color: red; } `; } }} `; return ( <div> <Label> <Input defaultChecked/> <LabelText>Foo</LabelText> </Label> <Label> <Input/> <LabelText $mode="dark">Foo</LabelText> </Label> <Label> <Input defaultChecked/> <LabelText>Foo</LabelText> </Label> <Label> <Input defaultChecked/> <LabelText $mode="dark">Foo</LabelText> </Label> </div> ); }; export default DoubleAmpersand;
- 또한, 특별한 동작인 "우선 순위 부스팅"이 발생합니다.
- 이는 혼합된 styled-components와 일반 CSS 환경에서 충돌하는 스타일이 있을 수 있는 경우 유용합니다
예제
import styled, {createGlobalStyle} from "styled-components"; // && a double ampersand alone has a special behavior called a "precedence boost"; // this can be useful if you are dealing with a mixed styled-components and vanilla CSS environment where there might be conflicting styles: const DoubleAmpersand2 = () => { const Thing = styled.div` && { color: blue; } `; const GlobalStyle = createGlobalStyle` div${Thing} { color: red; } `; return ( <div> <GlobalStyle/> <Thing> I'm blue, da ba dee da ba daa </Thing> </div> ); }; export default DoubleAmpersand2;
2. Attaching Additional Props
- 불필요한 래퍼를 피하기 위해 렌더링된 컴포넌트나 요소로 일부 props를 전달하는 경우 .attrs 생성자를 사용할 수 있습니다.
- 이를 사용하면 컴포넌트에 추가적인 props(또는 "속성")을 첨부할 수 있습니다.
- 이렇게 하면 예를 들어 정적 props를 요소에 첨부하거나 React Router의 Link 컴포넌트에 activeClassName과 같은 서드파티 prop을 전달하고, 컴포넌트에 더 동적인 props를 첨부할 수도 있습니다.
- .attrs 객체는 또한 컴포넌트가 받는 props를 전달하는 함수도 받습니다. 반환 값은 최종 props에 병합됩니다.
예제
import styled, {css} from "styled-components"; const BasicUsage = () => { const Input = styled.input.attrs(props => ({ // we can define static props type: "text", // and we can define dynamic ones $size: props.$size || "1em", }))` color: #BF4F74; font-size: 1em; border: 2px solid #BF4F74; border-radius: 3px; /* here we use the dynamically computed prop */ margin: ${props => props.$size}; padding: ${props => props.$size}; `; return (<div> <Input placeholder="A small text input"/> <br/> <Input placeholder="A bigger text input" $size="2em"/> </div>); }; export default BasicUsage;
2.1 Overriding .attrs
- styled 컴포넌트를 래핑할 때 .attrs가 가장 안쪽의 styled 컴포넌트부터 바깥쪽 styled 컴포넌트까지 적용됩니다.
- 이는 각각의 래퍼가 중첩된 .attrs 사용을 재정의할 수 있도록 하여, 스타일 시트에서 이전 선언을 덮어쓰는 방식과 유사합니다.
예제
import styled, {css} from "styled-components"; const OverridingAttrs = () => { const Input = styled.input.attrs((props) => ({ type: 'text', $size: props.$size || '1em', }))` border: 2px solid #bf4f74; margin: ${(props) => props.$size}; padding: ${(props) => props.$size}; `; // Input's attrs will be applied first, and then this attrs obj const PasswordInput = styled(Input).attrs({ type: "password", })` // similarly, border will override Input's border border: 2px solid aqua; `; return (<div> <Input placeholder="A bigger text input" $size="2em"/> <br/> {/* Notice we can still use the size attr from Input */} <PasswordInput placeholder="A bigger password input" $size="2em"/> </div>); }; export default OverridingAttrs;
'> Frontend > React' 카테고리의 다른 글
TIL-2024.05.11 - Alias 설정 (0) 2024.05.11 TIL-2024.05.08 - React - 014. Styled Component - advanced- 1 (0) 2024.05.09 TIL-2024.05.06 - React - 012. Styled Component - basic- 1 (0) 2024.05.08 TIL-2024.05.05 - React - 011. Render Props (0) 2024.05.08 TIL-2024.05.04 - React - 010. Recoil (0) 2024.05.04