본문 바로가기
TIL with Programmers

[TIL] 11/5 프론트엔드 심화2 - 몰랐던 부분 정리

by 보먀 2024. 11. 5.
728x90
반응형

 

1. useState 상태 변경 함수의 타입 정의

 

isFormOpen, setIsFormOpen 을 props 를 이용해 다른 컴포넌트로 보내어 사용해야 하는 상황에서는 props 의 타입을 정해줘야 한다. 

const [isFormOpen, setIsFormOpen] = useState(false);
import React, { FC } from 'react'
import { FiPlusCircle } from 'react-icons/fi'

type TFormProps = {
  isFormOpen: boolean,
  setIsFormOpen: 
  React.Dispatch<React.SetStateAction<boolean>>
}

const SideForm: FC<TFormProps> = ({isFormOpen, setIsFormOpen}) => {
  return (
    <div>
      // ...
      <FiPlusCircle onClick={() => {
        setIsFormOpen(!isFormOpen);
      }}/>
    </div>
  )
}

export default SideForm

 

 

궁금증1. React.Dispatch<React.SetStateAction<A>> 뭐하는 애지?

 

상태변경 함수를 정의하는 타입으로 A 에 상태변경 함수에 들어가는 인자값의 타입을 적어주면 된다. 

 

타입이 복잡해 보이니 뜯어보면 이렇다.

  • 상태 변경 함수 자체 타입: React.Dispatch<A>
  • 상태 변경 함수 인자 타입: React.SetState<A>

여기서 궁금증2..

궁금증2. 상태 변경 함수의 인자에 왜 또 인자 타입을 정의하는거지? 

 

상태 변경 함수는 두 가지 사용 방식이 있다. SetStateAction 은 useState 가 받을 수 있는 인자의 타입을 지정해줘야 하기 때문에 아래의 두 가지 방식을 모두 지정하기 위해 인자가 있는 것이라고 생각하면 된다. 

// 인자를 넣어주는 방식
setCount(3);
// 함수를 인자로 넣어주는 방식 (이전 값 참조할 때 사용)
setCount((prev) => prevCount + 1);

 

 

2. clsx 라이브러리

 

리액트에서 조건부로 className 을 적용하고 싶을 때 편하게 사용할 수 있는 라이브러리이다. 

 

기본적으로 이렇게 사용할 수 있다. 

clsx(
    'button', // 기본 클래스
    true && 'button-red', // 조건부 클래스
    false && 'button-blue' // 조건부 클래스
)

 

아래의 경우는 객체를 clsx 에 객체를 사용한 경우인데, 객체의 키는 클래스명이고 객체의 값은 조건이다. 만약 값이 true 라면 해당 클래스가 적용되고 false 라면 해당 클래스는 적용되지 않는다. 

{boardArray.map((board,index) => 
        <div key={board.boardId}
          onClick={() => setActiveBoardId(boardArray[index].boardId)}
          className={
            clsx(
              {
                [boardItemActive]: 
                  boardArray.findIndex(b => b.boardId === activeBoardId) === index,
              },
              {
                [boardItem]: 
                  boardArray.findIndex(b => b.boardId === activeBoardId) !== index
              }
            )
          }
        >
          <div >
            {board.boardName}
          </div>
        </div>
      )}
// ...

 

 

- 더 많은 사용법 리드미 참고

 

GitHub - lukeed/clsx: A tiny (239B) utility for constructing `className` strings conditionally.

A tiny (239B) utility for constructing `className` strings conditionally. - lukeed/clsx

github.com

 

 

3. 이벤트 객체의 타입은 ChangeEvent

 

ChangeEvent 는 HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement 등 다양한 HTML 요소와 함께 사용할 수 있다.

// Input 요소의 경우
const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
  setInputValue(e.target.value);
}

// TextArea 요소의 경우
const handleTextChange = ((e: ChangeEvent<HTMLTextAreaElement>) => {
    setText(e.target.value);
  })

 

 

4. Onblur Onclick OnMouseDown

 

글을 쓰고 체크 표시를 누르면 폼이 닫히면서 게시판이 등록되고 다른 곳을 누르면 폼이 닫히는 기능을 구현했는데, 체크 표시를 눌러도 닫히지 않는 문제가 생겼다. 

 

- 문제의 원인

폼 외에 다른 곳을 눌렀을 때 폼이 닫히는 기능 -> onBlur 이라는 이벤트로 구현

체크 표시를 눌렀을 때 폼이 닫히는 기능 -> onClick 으로 구현

-> onClick 이벤트보다 onBlur 이벤트가 먼저 발생하기 때문에 onBlur 이 우선 실행되어 click 이벤트가 무시됨.

 

- 문제 해결

onMouseDown 이벤트를 사용해서 해결할 수 있다. 

onClick 이벤트는 마우스로 눌렀다가 뗄 때 발생하고 onMouseDown 이벤트는 마우스가 눌릴 때 발생하기 때문에 onMouseDown 이벤트가 발생한 시점에서 blur 이벤트가 발생하더라고 onMouseDown 이벤트가 먼저 실행되기 때문에 클릭이 제대로 처리됨!

 

 

5. React.FC<T> vs FC<T>

 

그냥 React 를 import 했냐 안했냐의 차이

React 를 미리 import 했다면 조금 더 간결하게 쓸 수 있다. 

import React, { FC } from 'react'; // React 를 먼저 import 했기 때문에 FC 로 쓸 수 있음

const MyComponent: FC<Props> = ({ prop1, prop2 }) => {
  return <div>{prop1}</div>;
};
// React 를 import 하지 않았기 때문에 React.FC 로 써줘야 함
const MyComponent: React.FC<Props> = ({ prop1, prop2 }) => {
  return <div>{prop1}</div>;
};

 

728x90
반응형