> Frontend/React

TIL-2024.05.08 - React - 014. Styled Component - advanced- 1

Janku 2024. 5. 9. 07:32

 

 

 

Theming

- styled-components는 <ThemeProvider> 래퍼 컴포넌트를 내보내어 Theme 지원을 제공. 

- 이 컴포넌트는 context API를 통해 자신 아래의 모든 리액트 컴포넌트에 테마를 제공. 

- 렌더 트리에서 모든 styled-components는 제공된 테마에 액세스할 수 있으며, 이는 여러 수준으로 깊게 중첩되어 있어도 가능

 

 

기본 예제

import styled, {ThemeProvider} from 'styled-components';

const BasicTheming = () => {
    const Button = styled.button`
        font-size: 1em;
        margin: 1em;
        padding: 0.25em 1em;
        border-radius: 3px;

        /* Color the border and Text with Theme.main*/
        color: ${props => props.theme.color};
        border: ${props => props.theme.borderSize} solid ${props => props.theme.color};
    `;

    // We are passing a default theme for Buttons that arent wrapped in the ThemeProvider
    Button.defaultProps = {
        theme: {
            color: "#BF4F74",
            borderSize: "4px"
        }
    }


    const theme = {
        color: "mediumseagreen",
        borderSize: "1px"
    };

    return (
        <div>
            <Button> Normal</Button>
            <ThemeProvider theme={theme}>
                <Button>Themed</Button>
            </ThemeProvider>
        </div>
    );
};

export default BasicTheming;

 


 

Functional Theming

- theme prop에 함수를 전달.

- 이 함수는 트리 상위의 다른 <ThemeProvider>로부터 받은 부모 테마를 받아서 Theme 자체를 컨텍스트로 만들 수 있습니다. 

 

 

예제

import styled, {ThemeProvider} from 'styled-components';

const FunctionThemes = () => {
    const Button = styled.button`
        color: ${props => props.theme.fg};
        border: 2px solid ${props => props.theme.fg};
        background: ${props => props.theme.bg};

        font-size: 1em;
        margin: 1em;
        padding: 0.25em 1em;
        border-radius: 3px;
    `;


    // We are passing a default theme for Buttons that arent wrapped in the ThemeProvider
    Button.defaultProps = {
        theme: {
            color: "#BF4F74",
            borderSize: "4px"
        }
    };


    const theme = {
        fg: "#BF4F74",
        bg: "white"
    };

    // Functional Theme
    const invertTheme = ({fg, bg}) => ({fg: bg, bg: fg});

    return (
        <div>
            <ThemeProvider theme={theme}>
                <div>
                    <Button>Default Theme</Button>

                    <ThemeProvider theme={invertTheme}>
                        <Button>Inverted Theme</Button>
                    </ThemeProvider>
                </div>
            </ThemeProvider>
        </div>
    );
};

export default FunctionThemes;

 

 

 

- 이 두 번째 Button은 배경색과 전경색을 반전시키기 위해 두 번째 ThemeProvider를 사용합니다. invertTheme 함수는 상위 테마를 받아 새로운 테마를 생성합니다.

 

 


 

 

Refs

- styled 컴포넌트에 ref prop을 전달하면 스타일 대상에 따라 다음 중 하나가 제공됩니다

  • 1. 기본 요소를 대상으로 하는 경우 (예: styled.div) > 기본 DOM 노드가 제공.
  • 2. 사용자 지정 컴포넌트를 대상으로 하는 경우 (예: React.Component에서 확장된 컴포넌트) >  React 컴포넌트 인스턴스가 제공

 

예제

import React, {useRef} from 'react';
import styled from 'styled-components';

const Input = styled.input`
    padding: 0.5em;
    margin: 0.5em;
    color: #BF4F74;
    background: papayawhip;
    border: none;
    border-radius: 3px;
`;

const BasicRefs = () => {
    const inputRef = useRef(null);

    const handleMouseEnter = () => {
        if (inputRef.current) {
            inputRef.current.focus();
        }
    };

    const handleMouseLeave = () => {
        if (inputRef.current) {
            inputRef.current.blur();
        }
    };

    return (
        <Input
            ref={inputRef}
            placeholder="Hover to focus"
            onMouseEnter={handleMouseEnter}
            onMouseLeave={handleMouseLeave}
        />
    );
};

export default BasicRefs;