본문 바로가기
Web Study/TypeScript

리액트와 타입스크립트

by 쿠리의일상 2023. 4. 30.

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

  1. HTML DOM 요소를 컨트롤할 때
  2. 컴포넌트가 리렌더링 되더라도 값을 유지하는 변수로 사용할 때

 

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