리스트와 key

  • 반복되는 컴포넌트가 있다면 map 함수를 사용해 렌더링하는 것이 효율적
  • key
    • 연속적으로 setState를 호출하면 batch로 묶어서 처리가됨
    • 반복된 컴포넌트가 있을때 key는 어떤 컴포넌트에서 값이 바뀌었는지 파악하는데 도움이됨
    • key로 고유한 문자열을 사용하는 것이 좋음 -> 그렇지 않으면 해당 리스트의 내용이 변경 됐을때 꼬여서 이상한 위치의 내용이 변경 될 수 있음 따라서 항목의 순서가 바뀔 수 있는 경우 key에 인덱스 값을사용하면 오히려 성능 저하가 발생하거나 state 관련 문제가 발생할 수 있음
    • key는 형제 관계에서만 고유하면된다
    • key는 props로 전달되지 않음

함수 컴포넌트에서 이벤트 처리

  • camelCase 사용
  • false를 반환하는 것으로 기본 동작 방지 불가, preventDefault 필요
  • 합성 이벤트란?
  • addEventListener 필요없고 컴포넌트에 onClick 이렇게 한 후 콜백함수 등록하면됨
  • event bubbling 되는 부분은 stopPropagation으로 해제
  • 폼과 제어 컴포넌트
    • 제어컴포넌트 = input, textarea, select 등의 폼 엘리먼트 내용을 setState로 제어
    • 다중 입력 다루기
      • select -> react에서는 selected 옵션 대신 최상단 select 태그에 value 속성을 사용해 selected 된 option을 명시함
    • 제어 컴포넌트는 state가 사용 되기 때문에 이벤트 발생시 리랜더링 발생 시킴
  • 제어 컴포넌트 예시
export default function App() {
  const [input, setInput] = useState('');
  const onChange = (e) => {
    setInput(e.target.value);
  };

  return (
    <div className="App">
      <input onChange={onChange} />
    </div>
  );
}

비제어 컴포넌트

  • ref를 사용해 DOM의 값을 가져옴
  • 클래스 -> createRef, 함수 -> useRef
  • 제어 컴포넌트처럼 상태가 변경 되어도 리랜더링 발생 시키지 않음
  • 비제어 컴포넌트 예시
export default function App() {
  const inputRef = useRef(); // ref 사용
  const onClick = () => {
    console.log(inputRef.current.value);
  };

  return (
    <div className="App">
      <input ref={inputRef} />
      <button type="submit" onClick={onClick}>
        전송
      </button>
    </div>
  );
}

ref

  • 사용 사례: focus, 텍스트 선택 영역, 미디어 관리 등, 서드 파티 DOM 라이브러리를 React와 같이 사용할때
  • 함수 컴포넌트에서는 커스텀 컴포넌트에 ref 사용 불가능 (인스턴스가 없기 때문) -> 사용하려면 forwardRef 필요
  • ref 값은 ref.current로 접근 가능
  • forwardRef
    • 부모 컴포넌트가 자식 컴포넌트의 요소를 ref로 관리하고 사용할때 사용
    • 부모에서 useRef 를 ref props로 전달하고 자식에서 forwardRef를 사용해 컴포넌트를 forwardRef로 감싸서 ref를 parameter로 받는 것처럼 사용함
    • 하지만 자식 컴포넌트에서 ref 내용이 변경되면 부모는 알 수 없음
    • useImperativeHandle을 사용해 부모에서 자식 ref 요소를 간편하게 컨트롤 할 수 있음
  • mutable object
    • useRef로 상태값을 만들 수 있음 (변경 가능한 값을 담고 있는 상자), 따라서 useRef는 DOM ref만을 위한 hook이 아님
    • useRef 값은 변경해도 리랜더링이 발생하지 않음
  • callback ref
    • 함수를 ref에 넘겨 주는 방법
    • 자식에서 ref의 값이 변경된 경우 callback이 실행되어서 처리되도록 하는 방법
  • 합성 vs 상속
    • 컴포넌트 재사용성과 관련된 내용
    • 합성 = 컴포넌트에 다른 컴포넌트 담기 (props로 전달할 수 있는 것에 제한이 없기 때문)
    • 상속 = 컴포넌트를 상속 계층 구조로 작성을 권장할만한 사례가 아직 없음
  • 리액트로 생각하기
    • 데이터와 UI를 구분 -> 컴포넌트 구상
    • 정적인 버전을 먼저 만들기 -> 정적인 버전을 만들때는 state를 사용하지 않고 작성
    • 이 후 state 추가

😊