[React] Custom Component
August 26, 2022
Component Driven Development (CDD)
디자인과 개발 단계에서부터 재사용할 수 있는, 레고처럼 조립해 나갈 수 있는 부품 단위로 UI 컴포넌트를 만들어 나가는 개발
CSS-in-JS (ex. Styled-Component)
기능적(Functional) 혹은 상태를 가진 컴포넌트들로부터 UI를 완전히 분리해 사용할 수 있는 아주 단순한 패턴을 제공
Styled Components 문법
1. 컴포넌트 만들기
import styled from "styled-components";
const 컴포넌트이름 = styled.태그종류`
background: black;
color: white;
`;
import styled from "styled-components";
// const button1 = styled(재활용할 컴포넌트) 가능
const button1 = styled.button`
background: black;
color: white;
`;
2. Props 활용하기
import styled from "styled-components";
const button1 = styled.button`
background: ${(props) => props.skyblue ? "skyblue" : props.color};
color: white;
`;
export default function App() {
return (
<>
<Button1>Button1</Button1>
<Button1 skyblue>Button1</Button1>
</>
);
}
-
Props로 조건부 렌더링하기:
props.skyblue ? "skyblue" : "pink"
-
Props 값으로 렌더링하기:
props.skyblue ? "skyblue" : props.color
3. 전역 스타일 설정하기
GlobalStyle.js
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
button {
padding : 5px;
margin : 2px;
border-radius : 5px;
}
`
<GlobalStyle>
컴포넌트를 최상위 컴포넌트에서 사용해주면 전역에 <GlobalStyle>
컴포넌트의 스타일이 적용된다.
App.js
import GlobalStyle from './GlobalStyle'
export default function App() {
return (
<>
<GlobalStyle />
<button id="practice">Practice!</button>;
</>
)
}
Storybook
Component Driven Development를 하기 위한 도구
지원하는 주요 기능
- UI 컴포넌트들을 카탈로그화하기
- 컴포넌트 변화를 Stories로 저장하기
- 핫 모듈 재 로딩과 같은 개발 툴 경험을 제공하기
- 리액트를 포함한 다양한 뷰 레이어 지원하기
튜토리얼
npx storybook init
이 명령어는 package.json
을 보고 사용 중인 프론트엔드 라이브러리에 맞는 Storybook 사용 환경을 알아서 만들어주기 때문에, 꼭 React가 아니더라도 다양한 프론트엔드 라이브러리에서 사용할 수 있다.
useRef
React로 모든 개발 요구 사항을 충족할 수는 없다. 아래와 같이 DOM 엘리먼트의 주소값을 활용해야 하는 경우 특히 그렇다.
- focus
- text selection
- media playback
- 애니메이션 적용
- d3.js, greensock 등 DOM 기반 라이브러리 활용
아래 예시 코드처럼 useRef
로 DOM 노드, 엘리먼트, 그리고 React 컴포넌트 주소값을 참조할 수 있다.
function TextInputWithFocusButton() {
// const 주소값을_담는_그릇 = useRef(참조자료형)
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
{/* <input ref={주소값을_담는_그릇} type="text" /> */}
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>);
}