즉, Memoization이 된 결과값이 Memoized value
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); }, [] );- 컴포넌트가 마운트(소멸)시에만 호출되기에 값의 변경을 확인할 수 없다
- 마운트시에만 계산을 할 필요가 있을 때 위의 코드처럼 사용하면 된다
- useMemo() Hook과 유사하지만 값이 아닌 함수를 반환
- 컴포넌트가 랜더링 될 때마다 매번 함수를 새로 정의하는 것이 아니라
의존성 배열이 바뀐 경우에만 함수를 새로 정의하여 리턴
useCallback(콜백함수, 의존성 배열)
const memoizedCallback = useCallback( () => { doSomething(의존성 변수1, 의존성 변수2); }, [의존성 변수1, 의존성 변수2] );의존성 배열의 내용 변경 시 -> memoization된 콜백함수 반환
#useMemo()와 useCallback()
useCallback(함수, 의존성 배열); // 미 사용시 랜더링 될때마다 함수를 재생성한다
useMemo(() => 함수, 의존성 배열);
동일한 역할을 한다
- Reference를 사용하기 위한 Hook
- Reference : 특정 컴포넌트에 접근할 수 있는 객체
- useRef훅은 Reference를 반환한다
- Reference : current라는 속성을 포함
- current : 현재 참조하고 있는 Element
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속성을 변경한다고 해서 재랜더링 되지 않는다
돔노드의 변화를 알기위함
리액트는 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>
</>
);
}