#Memoized value

  • Memoized value를 리턴하는 Hook

#Memoization

  • useMemo, useCallback에서 나오는 개념
  • 컴퓨터에서는 최적화를 위해서 사용하는 개념
  • 비용이 높은, 연산량이 많이 드는 결과를 저장해 두었다가
    같은 입력값으로 함수를 호출하면
    새로 함수를 호출하지 않고
    이전에 저장해 두었던 호출결과를 바로 반환하는 것
  • 시간절약, 불필요 연산 생략, 컴퓨터 자원 절약

즉, Memoization이 된 결과값이 Memoized value

#useMemo()사용법

const memoizedValue = useMemo( // --> useMemo(create함수, []의존성배열)
  () => {
    // 연산량이 높은 작업을 수행하여 결과를 반환
    return computerExpensiveValue(의존성 변수1, 의존성 변수2);
  }, // memoizedValue를 반환하는 클래스 함수
  [의존성 변수1, 의존성 변수2] // 의존성 배열 
);

의존성 배열의 값이 변환될 경우에만
새로 create함수를 호출한다
그렇지 않을 경우
기존 함수를 반환한다

즉, 랜더링 될때마다 연산작업이 높은 작업이 들어오면 미리 저장된 Memoized value값으로 피할 수 있다

! 렌더링 하는 동안 useMemo()함수도 같이 실행된다.
때문에 랜더링동안 실행되지 말아야 할 작업은 useMemo()에 넣어서는 안된다
- SideEffect 같은 경우 랜더링 시 실행되면 안된다
- 서버에서 데이터를 받아오거나, 수동으로 DOM을 변경하는 작업등


의존성 배열을 넣지 않을 경우, 매 렌더링마다 함수가 실행 됨

const memoizedValue = useMemo(
  () => computeExpensiveValue(a, b)
);

매번 실행 되면서 자원을 잡아먹고, 변경되는 값도 없어 기존에 입력된 값의 변경인지도 확인 불가능


의존성 배열을 빈 배열로 할 경우

const memoizedValue = useMemo(
  () => {
    return computeExpensiveValue(a, b);
  },
  []
);

- 컴포넌트가 마운트(소멸)시에만 호출되기에 값의 변경을 확인할 수 없다
- 마운트시에만 계산을 할 필요가 있을 때 위의 코드처럼 사용하면 된다

#useCollback()

- useMemo() Hook과 유사하지만 값이 아닌 함수를 반환
- 컴포넌트가 랜더링 될 때마다 매번 함수를 새로 정의하는 것이 아니라
의존성 배열이 바뀐 경우에만 함수를 새로 정의하여 리턴

#useCallback()사용법

useCallback(콜백함수, 의존성 배열)

const memoizedCallback = useCallback(
  () => {
    doSomething(의존성 변수1, 의존성 변수2);
  },
  [의존성 변수1, 의존성 변수2]
);

의존성 배열의 내용 변경 시 -> memoization된 콜백함수 반환

#useMemo()와 useCallback()

useCallback(함수, 의존성 배열); // 미 사용시 랜더링 될때마다 함수를 재생성한다

useMemo(() => 함수, 의존성 배열);

동일한 역할을 한다

#useRef()

- Reference를 사용하기 위한 Hook
- Reference : 특정 컴포넌트에 접근할 수 있는 객체
- useRef훅은 Reference를 반환한다
- Reference : current라는 속성을 포함
- current : 현재 참조하고 있는 Element

#useRef() 사용법

const refContainer = useRef(초기값);

예제)

버튼 클릭시 input에 focus하도록 하는 코드

function TextInputWithFocusButton(props) {
  const inputElem = useRef(null); // 널값 대입
  const onButtonClick = () => { 
    // `current는 마운트된 input element를 카리킴
    inputElem.current.focus();  //  실제(본체) Element에 접근하여 focus()함수 호출   
  };
  return (
	<>
      <input ref={inputElem} type="text"/> // input태그에 inputElem이라는 객체를 넣음 
	  <button onClick={onButtonClick}> // 버튼 클릭시 온버튼 함수로 이동
        Focus the input
      </button>
    </>
  );
}
  • useRef() Hook은 내부의 데이터가 변경되었을 때 별도로 알리지 않는다.
    즉, current속성을 변경한다고 해서 재랜더링 되지 않는다

#Callback ref

돔노드의 변화를 알기위함
리액트는 ref가 다른 노드에 연결될 때마다 Callback을 호출하게 된다

function MeasureExample(props) {
	const [height, setHeight] = useState(0);
    
    const measuredRef = useCallback(node => {
    	if(node !== null){
        	setHeight(node.getBoundingClientRect().height);
        }
	}, []);
   
   	return (
      <> 
          <h1 ref={measuredRef}>안녕, 페라리</h1>
          <h2>위 헤더의 높이는 {Math.round(height)}px 입니다</h2>
      </>
    );
   
   
}
    
    
    
    
    
    
profile
페라리 타는 백엔드 개발자

0개의 댓글