> 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;