이 글은 제가 리액트+ 스타일 컴포넌트 배운지 10일차때 작성한 글이라 왜 이렇게 했지? 라는 부분이 많습니다.ㅎㅎ;; 추가로 ThemeProvider은 일부분에서 사용하기 보단 프로젝트 전반적으로 어떤 스타일을 공유해야할 때 주로 사용합니다
그래서 각기 다른 길이를 가지고 있는 컴포넌트에게 어떻게 스타일을 입혀주지?
ThemeProvider 사용법 말고 컴포넌트 분리자체가 궁금하면 1번 글 보러가세요
일단 어떻게든 분리는 했는데... 그래서 어떻게 style을 넣어줄지 고민이 되었어요. 그러던 중 ThemeProvider을 알게 되었음.
매번 노가다 안해도 괜찮음
스타일 선언 순서에 대한 일관성 확보 가능
컴포넌트 자체를 재사용하기 편함
이정도가 내가 생각한 ThemeProvider의 장점이에요. 더 있을 수도 있는데 아직 그거까지는 모르겠답니다. 나중에 알게되고 + 안귀찮으면 업데이트 할게용><
내 코드에서는 Input 컴포넌트겠죠? 일단 다시 코드를 봅시다
Input.tsx
import React from "react";
import Style from "./InputStyled";
type InputProps = {
type: string;
isRequired: boolean;
onInput: (e: React.ChangeEvent<HTMLInputElement>) => void;
id?: string;
value?: string;
minLength?: number;
maxLength?: number;
placeholder?: string;
inputRef?: React.RefObject<HTMLInputElement>;
onBlur?: (e: React.ChangeEvent<HTMLInputElement>) => void;
};
function Input({ isRequired, inputRef, ...props }: InputProps) {
return (
<Style.InputSection>
<Style.Input
{...props}
required={isRequired ? true : false}
ref={inputRef}
/>
</Style.InputSection>
);
}
export default Input;
이 친구가 어디서 사용되냐에 따라서 스타일이 바껴야해요 스타일 코드를 봐봅시다.
InputStyle.tsx
import styled from "styled-components";
const Style = {
InputSection: styled.section`
display: flex;
align-items: center;
justify-content: center;
gap: 5px;
width: ${(props) => props.theme.inputSectionWidth};
height: 6vh;
border-radius: 7px;
background: #ecebf1;
`,
Input: styled.input`
border: none;
text-align: center;
background: inherit;
width: ${(props) => props.theme.width};
font-size: ${(props) => props.theme.size};
letter-spacing: ${(props) => props.theme.spacing};
`,
};
두둥! 바뀌지 않는 애들은 똑같이 써주고 바껴야하는 친구들에게 어떤 속성을 줄건지 정해주는거에요. 하지만 props가 들어오지 않는 경우도 있겠죠? 그럴 땐 이렇게 defaul값을 정해준답니다.
Style.Input.defaultProps = {
theme: {
inputSectionWidth: "",
width: "",
size: "",
spacing: "0px",
},
};
export default Style;
이제 스타일 컴포넌트에 들어오는 theme의 속성이 있으면 그 값으로 위에 스타일이 바뀔거고 아니면 이 defaultProps를 가지고 스타일이 정해지는거랍니다
이제 사전 준비가 다 끝났어요!
이제 다시 cardNumberInput을 봐야해요.
스타일을 바꿔야하는 대상인 Input 컴포넌트를 로 감싸주고 ThemeProvider여기에 바뀔 theme을 보내줍니다. 그러면 스타일 컴포넌트에서 props.theme으로 해당 속성에 접근이 가능한거에요
const theme = {
inputSectionWidth: "100%",
width: "90%",
size: "20px",
spacing: "2px",
};
return (
<section>
<Style.Title>카드 번호</Style.Title>
<ThemeProvider theme={theme}>
<Input {...props} />
</ThemeProvider>
<InputGuide warningText={warningText} />
</section>
);
아직 저는 Input컴포넌트에서 간단한 몇가지만 이용해서 적용해보았지만 응용하면 반응형 이런식으로 가능해질 것 같네요! 그건 나중에 하게 되면 추가할게요(안귀찮으면) 밑에 참고자료 올려두겠습니당