useState
useState<타입명>(초기값) 형태로 사용
import React, { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState<number>(0);
return (
<div>
<div>{count}</div>
<button onClick={() => setCount((cur :number) => cur + 1)}>+</button>
<button onClick={() => setCount((cur :number) => cur - 1)}>-</button>
</div>
)
}
useRef
- HTML DOM 요소를 컨트롤할 때
- 컴포넌트가 리렌더링 되더라도 값을 유지하는 변수로 사용할 때
HTML DOM 요소를 컨트롤하려면
HTML태그명Element 의 타입으로 접근
const inputRef = useRef<HTMLInputElement>(null);
...
<input ref={inputRef} />
import React, { useRef, useState } from 'react'
export default function Input() {
const [string, setString] = useState<string>('');
const inputRef = useRef<HTMLInputElement>(null);
const handleChange = ():void => {
if(inputRef.current !== null)
setString(inputRef.current.value);
}
return (
<div>
<h1>{string === '' ? '값을 입력하시오' : string}</h1>
<input
ref = {inputRef}
onChange={handleChange} />
</div>
)
}
null 값이 들어갈 가능성을 제거해줘야 에러가 나지 않으므로 조건문으로 처리를 해줘야 한다.
const handleChange2 = (e: React.ChangeEvent<HTMLInputElement>) :void => {
setString(e.target.value);
}
React.ChangeEvent<HTML타입Element> 라는 타입으로 이벤트 객체에 접근할 수 있다.
변수처럼 쓰려면
useState 처럼 사용하면 됨
Props 사용하기
TS에선 전달, 사용되는 모든 데이터는 타입을 정해줘야 한다.
물론 props 도 마찬가지로, 보통 객체 형태로 전달이 되므로 구조 분해 할당으로 하나하나 타입을 선언해주거나 interface 또는 type 을 이용해준다.
매번 속성을 지정할 때마다 타입을 선언하는 것은 하드코딩하는 양도 늘어나고, 보내는 쪽 또는 받는 쪽 한 곳에서만 props 데이터를 확인할 수 있기에 불편하므로 interface를 사용하여 구현
보내는 부모 컴포넌트에 인터페이스로 보낼 속성의 타입을 정의하고 export 해주고 import 받아서 제공해준다.
export interface MyProps {
name : string,
age : number,
hobbies : string[],
}
function App() {
const p:MyProps = {
name : 'kim',
age : 20,
hobbies: ['1', '2'],
}
return (
<>
<Counter />
<Input />
<Props {...p} />
</>
);
}
export default App;
import { MyProps } from '../App';
export default function Props({
name, age, hobbies,
}: MyProps) {
return (
<div>
<h2>이름 : {name}</h2>
<h2>나이 : {age}</h2>
<h2>취미</h2>
{hobbies?.map((el) =>
<p>{el}</p>)}
</div>
);
}
Todo 리스트 TS 적용하여 만들기
export interface Task {
content: string,
isCompleted? : boolean,
}
export default function Todo() {
const [inputs, setInputs] = useState<string>('');
const inputRef = useRef<HTMLInputElement>(null);
const lists = useRef<Task[]>([]);
const addTask = () => {
const newTask :Task = {
content:inputs,
isCompleted: false,
}
lists.current.push(newTask);
if(inputRef.current !== null)
inputRef.current.value = '';
setInputs('');
}
return (
<div>
<input
ref={inputRef}
type='text'
onChange={(e :React.ChangeEvent<HTMLInputElement>): void => setInputs(e.target.value)}
/>
<button
onClick={addTask}
>
할 일 추가
</button>
<h1>할 일 목록</h1>
{lists.current.map((el) => <List {...el} />)}
</div>
)
}
import { Task } from './Todo';
export default function List({
content,
isCompleted
}: Task) {
return (
<>
<h3>{content}</h3>
<p>{isCompleted ? '완료' : '미완' }</p>
</>
)
}
간단한 형태로
'Web Study > TypeScript' 카테고리의 다른 글
타입스크립트 필수 문법 정리 (0) | 2023.04.25 |
---|---|
타입스크립트 기초 (1) | 2023.04.20 |
학원 끝! 타입스크립트 시작! (0) | 2023.04.20 |