728x90

https://react.dev/reference/react/useRef

 

useRef – React

The library for web and native user interfaces

react.dev

 

ref는 우리가 익히 알듯, 랜더링과 관계없는 값을 참조할 때 사용한다.

 

주로 js에서의 getElementById와같이 dom 요소에 직접 접근하고 싶을때 대신 사용하는것이 useRef다.

useRef를 통해 값을 변경하는 경우에는 화면이 재랜더링 되지 않으므로

 

보통 input의 focus 상태를 제어하거나, dom의 css를 직접 조작하고 싶을 때, 또는 className을 변경하고 싶을 때  사용한다.

 

예시 

function ToggleComponet() {
  const myRef = useRef(null);

  const toggleClassName = () => {
    if (myRef.current.classList.contains("second")) {
      myRef.current.classList.remove("second");
    } else {
      myRef.current.classList.add("second");
    }
  };

  return (
    <div>
      <div ref={myRef} className="first">
        test ref 
      </div>
      <button onClick={toggleClassName}>Toggle</button>
    </div>
  );
}

버튼을 클릭하는경우 "first" -> "first second" -> "first"로 변경된다.

 

 

다만 js의 돔 조작 방식처럼 내부에 새로운 요소(div등)을 추가하는 등 랜더링을 필요로 하는 작업들은 useState를 통해 처리하는것이 적절하다. 

 

createRef 는 useRef를 사용할 수 없는 클래스형 컴포넌트에서 사용된다 useRef와는 다르게 랜더링될때마다 다시 생성되어 이전의 값을 기억하지 않는다.

 

 

https://react.dev/reference/react/forwardRef

 

forwardRef – React

The library for web and native user interfaces

react.dev

forwardRef 는 기억해두는것이 좋다 ~.~ 

 

부모컴포넌트가 자식컴포넌트의 ref를 제어해야할 때 사용한다. 

보통 리액트의 데이터흐름은 자식 -> 부모 순이지만 가~끔 이렇게 부모요소가 자식요소를 제어해야하는 경우가 발생한다. 

그럴때 사용하는것이 forwardRef이다.

(위 페이지의 예제를 가져옴)

 

import { forwardRef } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
  const { label, ...otherProps } = props;
  return (
    <label>
      {label}
      <input {...otherProps} ref={ref} />
    </label>
  );
});

 

자식요소인 MyInput을 forwardRef 컴포넌트로 선언하면 

 

import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
  }

  return (
    <form>
      <MyInput label="Enter your name:" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}

부모요소인 Form에서 선언한 ref는 부모가 아닌 자식컴포넌트인 MyInput을 가리키게된다. 

따라서 핸들클릭을 통해 이벤트가 발생하면 자식요소인 input에 focus가 발생한다. 

728x90

https://ko.vite.dev/guide/

 

Vite

Vite, 프런트엔드 개발의 새로운 기준

ko.vite.dev

 

Vite는 

성능에 집중한 번들러로

 

개발 환경에서 코드를 변경할 때 parcel, webapack에 비해 빠른 속도를 자랑한다. 

 

이유는 vite의 코드 갱신 방식이 다른 번들러들과 다르기 때문인데, 다른 번들러들은 코드의 업데이트가 있을 때 전체 코드를 다시 번들링 하지만, vite는 브라우저의 요청에 따라 변경된 모듈만 전달하는 방식으로 화면을 갱신하기 때문에,

프로젝트의 코드 크기가 커질수록 갱신 속도가 느려지는 다른 번들러들에 비해, vite는 빠른 속도를 유지할 수 있다는 것이다. ~.~ 

 

또한 배포시에도 ESbuild(트랜스파일러), Rollup(트리셰이킹, 불필요한 코드를 쳐내고 번들로 합침)을 기반으로 동작하기때문에, 웹팩과 같이 증분 빌드를 지원하지는 않지만 빌드 속도 또한 매우 빠르다.

 

 

 

 

리액트 typescript 프로젝트를 vite 기반으로 생성하는 npm 명령어 

npm create vite@latest my-project-name --template react-ts

 

일할때는 webpack만을 사용해봤는데 개인적으로 공부할때 vite를 써보니 확실히 기본 설정도 간단하고 로드 속도도 빨라서 편하다고 느껴졌다. 

728x90

 

 

정적 타입 검사란 ? 타입스크립트가 기본적으로 제공하는 기능으로,

컴파일 단계에서 변수나 리턴값, 파라미터 등의 타입에러를 찾아주는 것을 말한다. 

 

동적 타입 언어인 javascript는 암묵적 타입 변환 등을 허용하기 때문에 서로 다른 타입간의 계산을 허용하는 경우도 있고,

그로인해 예기치못한 런타임 에러가 발생할 수도 있다. 

 

그러나 타입스크립트는 컴파일시에 모든 변수, 매개변수 등의 정적 타입 검사를 진행하기 때문에, 

런타임시 발생할 에러를 사전에 방지할 수 있다. 

 

 

예를 들어, 

 

자바스크립트의 경우에는 

let num = 30;
let strNum = "2";

let plus = num+strNum;
console.log(plus); // "302" 출력 ;

let minus = num - strNum;
console.log(minus); //28 출력

암묵적 타입 변환을 허용해서 덧셈 연산인 경우, 숫자를 문자열로 변환한 계산을 시도하고, 뺄셈 연산의 경우엔 문자열을 숫자로 바꾸는 것을 시도한다. 

 

그러나 타입스크립트는 위와 같은 암묵적 타입 변환을 허용하지 않고, 코드에서부터 타입 에러를 표시해준다. 

 

또한, 

tsconfig.json 파일을 수정해서 더욱 엄격한 모드로 변경하는 것도 가능하다. (any를 허용하지 않음)

728x90

타입 추론이란, 

타입을 코드상에 명시적으로 지정하지 않아도 컴파일러가 변수 or 상수의 값을 자동으로 추론해주는 것을 말한다. 

 

예를 들어서, 

const x = 22;

const y = 10;

const z = x+ y ;

일때 컴파일러는 z의 타입이 number임을 자동으로 추론한다.

 

재할당이 가능한 let의 경우에는,

 

let MyName = "Ann";

MyName = 223; //MyName의 타입을 string으로 추론중이므로 에러 발생!

 

이것은 함수의 리턴값이나 객체의 타입을 추론하는 경우에도 동일하다. 

 

그러나 const와 let의 타입 추론 방식은 조금 다르다. 

 

상수인 const 는 리터럴 타입, 변수인 let은 원시 타입 추론이 이루어진다. 

 

여기서 리터럴 타입이란, string, number 와 같이 넓은 의미의 타입이 아니라, 

const x = 30의 경우 x는 30 이라는 구체적인 리터럴 타입으로 추론되는것을 말한다.  

 

원시타입은 우리가 일반적으로 아는 string, number, boolean, undefined 등 포괄적으로 사용되는 타입을 말한다. 

 

 

재할당이 가능한 let은 넓은 범위의 원시 타입으로 추론되지만. 재할당이 불가능한 상수 const는 리터럴 타입으로 추론되는 것이다. 

728x90

타입스크립트를 사용하는 프론트앤드 개발자라면 반드시 사용하게되는 type과 interface ! 

둘의 차이를 알고 적재적소에 사용한다면  안정적이고, 유지보수가 용이한 높은 품질의 코드를 작성할 수 있게 될 것이다

 

 

interface 

'객체' 의 구조를 정의하는데 사용된다. 클래스기반의 코드를 작성하는데 주로 사용되며 병합이 가능해 확장 가능성이 있는 타입을 정의할 때 용이하다. 객체의 타입만 정의 가능. 

 

interface의 자동 병합 예시로는 

 

interface Family {
mother: string;
father: string;
}

interface Family {
daughter: string;
son :string;
}

 

이렇게 Family 인터페이스를 두 번 정의할 경우 

첫번째 내용에 두번째 내용이 덧씌워지거나 오류가 발생하지 않고,

 

interface Family{
mother:string;
father:string;
daughter:string;
son:string
}

이렇게 하나로 병합된다는 특징을 가지고 있다. 

 

 

 

type

객체 뿐만 아니라 모든 요소의 타입 정의가 가능하다. 유니온 타입이나, 컴포넌트의 props, state, 이벤트 등의 타입도 정의가 가능해서 React 환경 개발에서는 type을 주로 사용한다. 

 

**유니온 타입 : 여러 타입 중 하나를 선택하는 것

type Info = { phoneNum : string | number; }  //유니온 타입 예시

 

 

interface와 type은 확장 방식도 다르다. 

 

//interface의 경우

interface Member {
name:string;
age: number
}

interface Student extends Member {
stuId:number;
major:string;
}


//type 의 경우

type Member = {
name:string;
age: number
}

Type Teacher = Member & {
tcId:number;
major:string;
}
}

 

 

 

728x90

 

https://emotion.sh/docs/typescript

 

Emotion – TypeScript

Emotion includes TypeScript definitions for @emotion/react and @emotion/styled. These definitions infer types for css properties with the object syntax, HTML/SVG tag names, and prop types. @emotion/react The easiest way to use the css prop with TypeScript

emotion.sh

이모션 공식 문서대로 

 

tsconfig.json 파일 안에 

 

{
.
.
.
.

"jsx": "react-jsx",
"jsxImportSource": "@emotion/react"
}

 

이 부분을 추가하자!

 

 

 

 

css-in-js 스타일 라이브러리중에 emotion이 코드도 깔끔하고 수정이 쉬워서 자주 사용중인데

프로젝트에 typescript를 도입하니 여기저기 에러가 튀어나온다 ...

 

번들러랑 바벨 다루는게 더 익숙해져야겠지 ~.~ 

728x90

 

npm run start  또는 

yarn start 등을 사용해 리액트 프로젝트를 실행했을 때,

react-scripts 관련 오류가 발생할 때가 있다. 

 

보통은 npm install --save react-scripts 또는

yarn add react-scripts를 입력해 설치하면 문제가 해결되지만 

 

typescript를 사용하는 경우엔 위의 방법으로 해결이 안되는 경우가 있다. 

 

그럴땐 우선 package.json 파일 안의 dependencies를 살펴보자 

 

  "dependencies": {
        .
        .
        .
        .
        .
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-router-dom": "^6.24.0",
    "react-scripts": "5.0.0",
    "typescript": "^5.5.3",
    }

나처럼 react-scripts가 5버전 이상인 경우에는

typesciprt가 4버전까지 지원이 된다. 

 

(2024.7 기준. 이후 버전에는 달라질 수도 있음)

나의 경우엔 "typescript" :  5.5.3 버전이 설치되어 있었는데 

저 부분을 ^4.9.5로 수정한 후 다시 실행했더니

정상적으로 로컬호스트가 실행되었다! 

 

 

 

 

 

728x90

+ Recent posts