Programming/TS

[Typescript] React with Typescript 1

w00se 2021. 6. 20. 12:10

https://pixabay.com/ko/photos/오래-된-마-건물-거리-황혼-6300696/

Typescript도 연습하고 React에도 적응하기 위해 기초부터 다시 연습하려 합니다.

연습은 벨로퍼트님의 '벨로퍼트와 함께하는 모던 리액트'로 진행했습니다.

 

해당 게시글은 React를 Typescript로 연습하면서 타입 선언, 기존 Javascript를 사용했을 때와 다른 점을 위주로 기록했습니다.

React에 대한 개념과 자세한 설명은 아래 링크에서 확인 가능합니다😊

https://react.vlpt.us

 

벨로퍼트와 함께하는 모던 리액트 · GitBook

벨로퍼트와 함께하는 모던 리액트 본 강의자료는 패스트캠퍼스 온라인 강의에서 제공하는 리액트 강의에서 사용되는 강의 문서입니다. 이 튜토리얼은 여러분들이 JavaScript 의 기초를 잘 알고있

react.vlpt.us

 

Props의 각 속성에 타입을 지정할 수 있다.

 

Counter.tsx

import React, { useState } from 'react';

// props의 각 속성에 타입을 선언 
interface CounterProps {
    currentNum: number,
}

function Counter(props: CounterProps){
    const [curNum, setCurNum] = useState<number>(props.currentNum); // useState method 역시 generic으로 type 지정 가능

    const increaseNumber = () => {
        setCurNum(curNum+1);
    }

    const decreaseNumber = () => {
        setCurNum(curNum-1);
    }

    return (
        <>
            <div>
                <div>{curNum}</div>
                <button onClick={increaseNumber}>+</button>
                <button onClick={decreaseNumber}>-</button>
            </div>
        </>
    )
}

export default Counter;

 

event에도 타입을 지정해야 한다.

타입을 any로 지정하는 것보다는 명확한 타입을 명시하는 것이 좋습니다.

event의 타입은 해당 이벤트 호출 부분에 커서를 올려두면 타입을 확인할 수 있습니다.

 

InputSample.tsx

import React, { useState } from 'react';

interface InputSampleProps {
    initialText: string
}
function InputSample(props: InputSampleProps) {
    const [inputedText, setInputedText] = useState<string>(props.initialText);
    
    const onChange = (e: React.ChangeEvent<HTMLInputElement>) => { // 이벤트의 타입은 onChange에 커서를 올려두면 나옵니다.
        setInputedText(e.target.value);
    }
    return (
        <>
            <input onChange={onChange} value={inputedText}/>
            <div>{`입력된 값: ${inputedText}`}</div>
        </>
    )
}

export default InputSample;

 

InputMultiSample.tsx

import React, { useState } from 'react';

interface InputSampleProps {
    initialText?: string
}

type inputStateType = { // state 초기 값에 맞게 타입 지정
    test1: string,
    test2: string,
}

function InputMultiSample(props: InputSampleProps) {
    const [inputedText, setInputedText] = useState<inputStateType>({ test1: "", test2: "" });
    const { test1, test2 } = inputedText; // 비구조화 할당 
    
    const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const { name, value } = e.target;

        setInputedText({
            ...inputedText, // spread 연산
            [name]: value // key에 대괄호를 사용해서 동적인 key에 값을 할당할 수 있다.
        });
    }
    return (
        <>
            <input onChange={onChange} name={"test1"} value={test1}/>
            <input onChange={onChange} name={"test2"} value={test2}/>
            <div>{`입력된 test1: ${test1}`}</div>
            <div>{`입력된 test2: ${test2}`}</div>
        </>
    )
}

export default InputMultiSample;

 

객체 안의 key를 대괄호로 지정하는 것에 대한 설명은 아래 링크에서 확인 가능합니다.

https://medium.com/@bretdoucette/understanding-this-setstate-name-value-a5ef7b4ea2b4

 

spread 연산자를 사용하면 객체의 각 속성 값을 복사한 후 새로운 객체를 생성합니다.

spread 연산자 뒤에 기존 객체에 있는 속성 값을 변경하면 수정이 됩니다.

let test = {
    "val1": 123,
    "val2": 456,
}

test = { ...test, "val1": 1000000, "val3": 789 }

console.log(test) // 출력 값: { val1: 1000000, val2: 456, val3: 789 }

 

UseRef에도 타입을  지정할 수 있다.

RefSample.tsx

import React, { useState, useRef } from 'react';

interface InputSampleProps {
    initialText?: string
}

type inputStateType = {
    test1: string,
    test2: string,
}

function RefSample(props: InputSampleProps) {
    const inputTest1 = useRef<HTMLInputElement>(null); // useRef 역시 타입을 지정할 수 있다. type은 참조하려는 DOM Element의 타입으로 지정하면 된다.
    const [inputedText, setInputedText] = useState<inputStateType>({ test1: "", test2: "" });
    const { test1, test2 } = inputedText;
    
    const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const { name, value } = e.target;

        setInputedText({
            ...inputedText,
            [name]: value
        });
    }

    const onClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
        setInputedText({
            test1: "",
            test2: "",
        });

        if(!inputTest1.current) {
            return;
        }

        inputTest1?.current.focus();
    }

    return (
        <>
            <input ref={inputTest1} onChange={onChange} name={"test1"} value={test1}/>
            <input onChange={onChange} name={"test2"} value={test2}/>
            <button onClick={onClick} >초기화</button>
            <div>{`입력된 test1: ${test1}`}</div>
            <div>{`입력된 test2: ${test2}`}</div>
        </>
    )
}

export default RefSample;

 

 


참고 자료

https://react.vlpt.us - 벨로퍼트와 함께하는 모던 리액트

https://medium.com/@bretdoucette/understanding-this-setstate-name-value-a5ef7b4ea2b4 - Bret Doucette Medium