본문 바로가기

프론트엔드관련 책예제실습정리/리기술요약

08hooks/useMemo,useCallback,useRef

1.useMemo

렌더링 과정에서 특정값이 바뀌었을때만 연산을 실행

//average.js

import React, { useState, useMemo } from "react";

const getAverage = (numbers) => {
  console.log("평균값계산");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");
  const onChange = (e) => {
    setNumber(e.target.value);
  };
  const onInsert = () => {
    const nextList = list.concat(parseInt(number));
    setList(nextList);
    setNumber("");
  };
  const avg = useMemo(() => getAverage(list), [list]);
  return (
    <div>
      <input value={number} onChange={onChange} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>평균값</b>
        {avg}
        {/* {getAverage(list)} */}
      </div>
    </div>
  );
};
export default Average;

2.useCallback 활용하여 최적화

렌더링 자주 발생, 컴포넌트 갯수 많아질경우 최적화시킬수 있다.

import React, { useState, useMemo, useCallback } from "react";

const getAverage = (numbers) => {
  console.log("연산중..");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");

  const onChange = useCallback(e=>{
    setNumber(e.target.value);
  },[])
  const onInsert = useCallback(()=>{
    const nextList = list.concat(parseInt(number))
    setList(nextList)
    setNumber('')
  },[number,list])
  // const onChange = (e) => {
  //   setNumber(e.target.value);
  // };
  // const onInsert = () => {
  //   const nextList = list.concat(parseInt(number));
  //   setList(nextList);
  //   setNumber("");
  // };
  const avg = useMemo(() => getAverage(list), [list]);
  return (
    <div>
      <input value={number} onChange={onChange} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>평균값</b>
        {avg}
      </div>
    </div>
  );
};

export default Average;

3.useRef 활용하여 함수형 컴퍼넌트에서 ref를 활용(특정 dom을 선택)

import React, { useState, useMemo, useCallback, useRef } from "react";

const getAverage = (numbers) => {
  console.log("연산중..");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");
  const inputEl = useRef(null);

  const onChange = useCallback((e) => {
    setNumber(e.target.value);
  }, []);
  const onInsert = useCallback(() => {
    const nextList = list.concat(parseInt(number));
    setList(nextList);
    setNumber("");
    inputEl.current.focus();
  }, [number, list]);
  // const onChange = (e) => {
  //   setNumber(e.target.value);
  // };
  // const onInsert = () => {
  //   const nextList = list.concat(parseInt(number));
  //   setList(nextList);
  //   setNumber("");
  // };
  const avg = useMemo(() => getAverage(list), [list]);
  return (
    <div>
      <input value={number} onChange={onChange} ref={inputEl} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>평균값</b>
        {avg}
      </div>
    </div>
  );
};

export default Average;