241122

우지끈·2024년 11월 22일

useRef, FormData

둘 다 비제어 컴포넌트 \to input 태그에서 value 값이 바껴도 리렌더링 x

useRef

import { useRef, useState } from 'react';

function TodoListWithUseRef() {
  const inputRef = useRef(null);
  const [todos, setTodos] = useState([]);

  const handleAddTodo = (e) => {
    e.preventDefault();
    const newTodo = inputRef.current.value.trim();
    if (newTodo) {
      setTodos([...todos, newTodo]); // 새로운 항목 추가
      inputRef.current.value = ''; // 입력 필드 초기화
    }
  };

  return (
    <div>
      <h2>Todo List</h2>
      <form onSubmit={handleAddTodo}>
        <input type="text" ref={inputRef} placeholder="Enter a task" />
        <button type="submit">Add</button>
      </form>

      <ul>
        {todos.map((todo, index) => (
          <li key={index}>{todo}</li>
        ))}
      </ul>
    </div>
  );
}

export default TodoListWithUseRef;
  • inputRef.current: input 태그 전체 \to inputRef.current.value를 통해 input 태그의 value에 접근
    - trim() 쓰는 이유: 앞 뒤 공백 잘라주기 위해
  • input 태그가 적을 때 사용하는게 좋음
  • 성능 측면에서는 FormData보다 빠름

FormData

import React, { useState } from 'react';

function TodoListWithFormData() {
  const [todos, setTodos] = useState([]);

  const handleAddTodo = (e) => {
    e.preventDefault();
    const formData = new FormData(e.target);
    const newTodo = formData.get('todo').trim(); // 'todo' 필드 값 가져오기

    if (newTodo) {
      setTodos([...todos, newTodo]); // 새로운 항목 추가
      e.target.reset(); // 입력 필드 초기화
    }
  };

  return (
    <div>
      <h2>Todo List</h2>
      <form onSubmit={handleAddTodo}>
        <input type="text" name="todo" placeholder="Enter a task" />
        <button type="submit">Add</button>
      </form>

      <ul>
        {todos.map((todo, index) => (
          <li key={index}>{todo}</li>
        ))}
      </ul>
    </div>
  );
}

export default TodoListWithFormData;
  • e.target: form 태그
  • formData.get("todo"): form 태그 안에서 name이 todo인 input의 value를 가져옴
  • e.target.reset(): 입력 필드 초기화
  • form 안에 input이 많을 때 쓰면 좋음
  • 코드가 직관적임

memo, useMemo, useCallback

  • memo \to 컴포넌트를 캐싱: 부모 컴포넌트 리렌더링 시 캐싱된 컴포넌트는 리렌더링하지 않고 재사용하는 API(단 props가 변하지 않았을 때)
    - 사용법: memo(함수컴포넌트)

  • useMemo \to 계산결과값을 캐싱: 계산 비용이 많이 드는 함수의 결과값에 사용할 때 특히 효과적(주로 객체나 배열)
    - 기준: 계산 시간이 1ms 이상이면 memoiozation ㄱㄱ (console.time, console.timeEnd 찍어보기)
    - 사용법: useMemo( () => {함수}, [] )

  • useCallback \to 함수정의를 캐싱: 리렌더링 시 재사용(함수) \to 의존성 배열에 변화 없으면 함수 재생성 절대 x
    - 사용법: useCallback(함수, [])

memoization 꿀팁:

  • 개발 어느정도 끝내고 컴포넌트에 콘솔 찍어보고 어떻게 씌우면 좋을지 생각해보기~
  • Context Provider 안에 들어가는 컴포넌트들은 다 useCallback 씌워주기 \to 전역 상태에서 관리되기에 다른 곳에서 의존성 배열에 들어가게 될 수도 있음
  • Custom Hook에 들어가는 함수들도 useCallback 씌워주는게 좋음 \to 위와 마찬가지로 다른 컴포넌트 안에서 어떻게 쓰일지 모르기때문

Custom Hook

  • 안에 ui 절대 넣으면 x \to 얘는 그냥 <<함수>>임
  • 함수 안에서 useState, useEffect 같은 리액트 내장훅 사용 가능
  • 이름은 use로 시작하게 지을 것
  • jsx ㄴㄴ \to js oo

0개의 댓글