한 걸음씩
TypeScript props, state, forms, themes 본문
1. Props
▷ Props
- PropTypes는 prop의 존재 여부를 알려주긴 하지만 코드가 실행된 이후에 알 수 있다
- 반면에, 타입스크립트는 코드가 실행되기 전에 오류를 확인할 수 있다
▷ Optional Props
- 타입스크립트에서 컴포넌트의 속성 중 일부가 반드시 필요하지 않을 때 사용하는 기능
- 일부 속성이 있을 수도 있고 없을 수도 있으며, 필요에 따라 전달할 수 있는 속성
▷ interface
- object shape(객체모양)을 타입스크립트에게 설명해 주는 타입스크립트의 개념
- object가 어떤식으로 보일지 설명해 주는 것
// App.tsx
import Circle from './Circle'
function App() {
return (
<div>
<Circle borderColor="black" bgColor="teal" />
<Circle text="im here" bgColor="tomato" />
</div>
)
}
export default App
// Circle.tsx
import styled from 'styled-components'
// Container(스타일 컴포넌트)의 타입
interface ContainerProps {
bgColor: string
borderColor: string
}
// Circle 컴포넌트가 받은 props의 타입
interface CircleProps {
bgColor: string // required
borderColor?: string // optional
text?: string // optional prop
}
const Container = styled.div<ContainerProps>`
display: flex;
justify-content: center;
align-items: center;
color: white;
width: 200px;
height: 200px;
background-color: ${props => props.bgColor};
border-radius: 50%;
border: 5px solid ${props => props.borderColor};
`
// Circle 컴포넌트는 bgColor를 받아 Container에 보냄
function Circle({ bgColor, borderColor, text = 'default text' }: CircleProps) {
// props에 기본값 설정하기: text로 전달받은 텍스트가 없는 경우 'default text'을 기본값으로 표시
return (
<Container bgColor={bgColor} borderColor={borderColor ?? bgColor}>
{/* borderColor가 있다면 borderColor사용하고, 아니라면 bgColor사용하기 */}
{text}
</Container>
)
}
export default Circle
※ Nullish Coalescing 연산자
- 자바스크립트에서 null 또는 undefined인 경우에만 우측의 값으로 대체하는 연산자
- 'borderColor ?? bgColor'에서 borderColor가 null 또는 undefined인 경우 bgColor의 값으로 대체하고, 아니라면 borderColor의 값 그대로 사용한다
2. State
- 타입스크립트는 useState의 default값에 따라 어떤 타입을 쓸 건지 알고 있다
const [counter, setCounter] = useState(0)
const [counter, setCounter] = useState<number>(0)
const [counter, setCounter] = useState('hello')
const [counter, setCounter] = useState<string>('hello')
const [counter, setCounter]= useState(true)
const [counter, setCounter]= useState<boolean>(true)
3. Forms
// App.tsx
import React, { useState } from 'react'
function App() {
const [value, setValue] = useState('')
// React.js에서 타입을 모른다면 구글링!
// 타입스크립트는 이 onchange 함수가 InputElement에 의해서 실행될 것을 알고 있다
const onChange = (event: React.FormEvent<HTMLInputElement>) => {
// React.js에서는 currentTarget사용. target과 동일함
// 구조 분해 할당 사용
const {
currentTarget: { value },
} = event
setValue(value)
}
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
console.log('hello', value)
}
return (
<div>
<form onSubmit={onSubmit}>
<input
value={value}
onChange={onChange}
type="text"
placeholder="username"
/>
<button>Log in</button>
</form>
</div>
)
}
export default App
- 타입스크립트를 사용하여 각 이벤트의 타입을 명시하면 코드의 안정성을 높이고, 잘못된 타입 사용으로 인한 오류를 사전에 방지할 수 있다
- https://legacy.reactjs.org/docs/events.html
4. Themes
▷ styled.d.ts
- styled.d.ts 파일은 타입스크립트에서 외부 라이브러리 또는 모듈에 대해 타입을 지정할 때 사용하는 파일
- styled-components 라이브러리의 타입을 확장하여 사용자 정의 테마를 지정
// styled.d.ts
import 'styled-components'
// styled-components 모듈에 대한 타입을 정의하겠다는 의미
declare module 'styled-components' {
// DefaultTheme 인터페이스는 styled-components 라이브러리에서 기본적으로 제공하는 테마를 나타내는 인터페이스
// DefaultTheme 인터페이스 확장하여 사용자 정의 테마를 지정하는 부분
export interface DefaultTheme {
textColor: string
bgColor: string
}
}
▷ index.tsx
- ThemeProvider는 styled-components 라이브러리에서 제공하는 컴포넌트로 전역적으로 테마를 적용할 때 사용된다
- ThemeProvider는 'theme' props를 통해 테마 객체를 전달받는다.(App.tsx)
- 이 테마 객체는 DefaultTheme 인터페이스를 따르는 객체여야 한다(theme.ts)
import React from 'react'
import ReactDOM from 'react-dom/client'
import { ThemeProvider } from 'styled-components'
import App from './App'
import { darkTheme, lightTheme } from './theme'
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
<React.StrictMode>
<ThemeProvider theme={lightTheme}>
<App />
</ThemeProvider>
</React.StrictMode>
)
▷ theme.ts
- .ts는 타입스크립트만을 포함한 확장자
- 아래의 theme.ts에서 lightTheme과 darkTheme객체를 styled-components 라이브러리의 DefaultTheme 인터페이스를 따르는 방식으로 정의하고, 해당 객체들을 export 하고 있다
- lightTheme, darkTheme 객체들은 styled-components의 ThemeProvider를 사용하여 전역적으로 테마를 적용할 수 있다
import { DefaultTheme } from 'styled-components'
export const lightTheme: DefaultTheme = {
bgColor: 'white',
textColor: 'black',
btnColor: 'tomato',
}
export const darkTheme: DefaultTheme = {
bgColor: 'black',
textColor: 'white',
btnColor: 'teal',
}
▷ App.tsx
- .tsx는 JSX 문법을 사용하는 React + TypeScript 코드를 사용하는 확장자를 말한다
import React, { useState } from 'react'
import styled from 'styled-components'
// index.tsx의 ThemeProvider 컴포넌트에서 'theme' props를 사용하여 테마 지정
const Container = styled.div`
background-color: ${props => props.theme.bgColor};
`
const H1 = styled.h1`
color: ${props => props.theme.textColor};
`
function App() {
return (
<Container>
<H1>protected</H1>
</Container>
)
}
export default App
'React' 카테고리의 다른 글
[React] react hook form (0) | 2023.08.10 |
---|---|
React Router V6 (0) | 2023.08.02 |
리액트 총정리 (0) | 2023.07.30 |
[React] Hooks 10개 (0) | 2023.07.25 |
React + TypeScript 설치 방법 (0) | 2023.07.20 |