본문 바로가기
{React}

10.03.22{코딩일기} 벨로퍼트와 함께하는 모던 리액트 1-12~13 챕터리뷰

by Davey 2022. 10. 3.
728x90

[ 새롭게 알게 된 것 ]


1. useRef의 또 다른 용도는 변수 관리


챕터10에서 DOM을 선택하는 용도외에도, 컴포넌트 안에서 조회 및 수정할 수 있는 변수를 관리하는 것임.

하지만 useRef로 관리하는 변수는 값이 바뀌어도 리렌더링에 영향주지 않음.

하지만 값이 바뀐 변수는 바로 조회 및 이용 가능함.


2. useState가 있는데 굳이 useRef를 사용해 컴포넌트 외부에 변수를 선언하는 이유


컴포넌트 내부에 변수를 선언하고 useState로 관리하면, 렌더링 될때마다 값이 초기화 되는 현상이 있기 때문임.

대신 useRef로 관리하면 전역으로 맨 마지막에 업데이트 한 값을 유지해야 할때, 컴포넌트가 렌더링되도 영향 안받음.

따라서 용도에 따라 적절한 Hook 사용의 중요성을 느낌.


3. 왜 useRef는 변수값이 바뀌어도 리렌더링 되지 않는가?


useRef는 heap 영역에 저장됨.

어플리케이션이 종료되거나 가비지 컬렉팅 될 때까지 참조값 연산이 항상 true를 반환함.

참조할 때 마다 같은 메모리 주소를 갖게되서 항상 ===연산이 true를 반환하기 때문.


4. useRef로 관리하면 좋은 값


setTimeout, setInterval을 통해 만들어진 id

외부 라이브러리를 사용하여 생성된 인스턴스

scroll 위치


5. useRef로 변수를 관리하는 방법 예시


APP컴포넌트가 아닌 다른 컴포넌트 내부에 있던 배열은 APP컴포넌트로 꺼내와서 선언

function App() {
const users = {

{ id: 1, ...},
{id :2, ...},
{id: 3, ...}

}

const nextId = useRef(4) ;
const onCreate = () => {
....
nextId.cureent += 1
}
}


5. useRef의 .current의 용도는 변수의 현재값을 조회 및 수정임


useRef의 .current 값의 기본은 true인데 useRef()안에 파라미터를 설정하면 해당 값이 초기값이 된다.

만약 let bluevulpe = useRef(4)로 useRef객체를 선언했다면 bluevulpe.current로 현재값 id값 조회가 가능.

값을 수정하려면 이벤트가 발생할 컴포넌트에 bluevulpe.current.focus() 해준 다음,

함수를 통해 bluevulpe.current += 1 해주면됨


6. useRef로 배열 자료구조 변수에 항목 추가 하는 법


부모컴포넌트인 App에서 상태관리를 하게 하고,

input의 값을 아래와같이 useState로 선언한 다음

이벤트로 등록할 함수들을 props로 넘겨주면 끝

단, 이때 push, splice, sort등의 함수를 사용하면 안됨.

이전 챕터에서 언급했듯이 객체의 불변성을 지켜주어야 컴포넌트성능에 좋기 때문.

대신 spred 연산자나 concat을 사용해 항목을 추가해주면 됨.

아래 예시는 useRef로 user id값을 상태관리해주고, user 객체 값은 state로 관리하며 항목 추가해주는 함수 onCreate

case1. spread 사용

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers([...users, user]);

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

case2. concat사용

const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email
    };
    setUsers(users.concat(user));

    setInputs({
      username: '',
      email: ''
    });
    nextId.current += 1;
  };

차이를 눈여겨 보면 좋음



728x90

댓글