[React] Additional Hooks (1)

OROSYΒ·2021λ…„ 10μ›” 4일
1

React

λͺ©λ‘ 보기
26/27
post-thumbnail

πŸͺ Additional Hooks (1)

React Hooksμ—λŠ” μ—¬λŸ¬ λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

  • useReducer
  • useMemo
  • useCallback
  • useRef
    ...

μœ„μ™€ 같이 μ΄μ€‘μ—μ„œ λŒ€ν‘œμ μœΌλ‘œ μ‚¬μš©λ˜λŠ” 좔가적인 Hooks에 λŒ€ν•΄ μ•Œμ•„λ³΄λŠ” μ‹œκ°„μ„ 가져도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€. κ°„λ‹¨ν•œ κ°œλ…κ³Ό μ½”λ“œλ₯Ό μ΄μš©ν•˜μ—¬ μ„€λͺ…ν•˜κΈ° λ•Œλ¬Έμ— 좔가적인 λ‚΄μš©μ€ λ¦¬μ•‘νŠΈ κ³΅μ‹λ¬Έμ„œλ₯Ό μ°Έμ‘°ν•΄μ£Όμ‹œκΈ° λ°”λΌκ² μŠ΅λ‹ˆλ‹€.

πŸ“‰ useReducer

처음으둜 μ‚΄νŽ΄λ³Ό 것은 useReducerλΌλŠ” ν›…μž…λ‹ˆλ‹€. μ΄λŠ” state 값을 λ³€κ²½ν•˜λŠ” useState의 ν™•μž₯판이라고 λ³΄μ‹œλ©΄ λ©λ‹ˆλ‹€.

reducerλŠ” ν˜„μž¬ μƒνƒœμ™€, μ—…λ°μ΄νŠΈλ₯Ό μœ„ν•΄ ν•„μš”ν•œ 정보λ₯Ό 담은 μ•‘μ…˜(action) 값을 전달 λ°›μ•„ μƒˆλ‘œμš΄ μƒνƒœλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€. reducer ν•¨μˆ˜μ—μ„œ μƒˆλ‘œμš΄ μƒνƒœλ₯Ό λ§Œλ“€ λ•ŒλŠ” κΌ­ λΆˆλ³€μ„±μ„ μ§€μΌœμ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

  • λ‹€μˆ˜μ˜ ν•˜μœ—κ°’μ„ ν¬ν•¨ν•˜λŠ” λ³΅μž‘ν•œ 정적 λ‘œμ§μ„ λ§Œλ“œλŠ” 경우
  • λ‹€μŒ stateκ°€ 이전 state에 의쑴적인 경우
  • Reduxλ₯Ό μ•ˆλ‹€λ©΄ μ‰½κ²Œ μ‚¬μš© κ°€λŠ₯

μ½”λ“œλ₯Ό λ¨Όμ € 보기 전에, κ°œλ…μ„ μ •λ¦¬ν•˜κ³  가도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€. useReducerλΌλŠ” 훅을 μ‚¬μš©ν•˜κ²Œ 되면 reducer와 dispatchλ₯Ό ν™œμš©ν•˜κ²Œ λ©λ‹ˆλ‹€. 이에 λŒ€ν•œ κ°„λ‹¨ν•œ κ°œλ…λ§Œ μ •λ¦¬ν•΄λ³ΌκΉŒμš”?

reducer

stateλ₯Ό λ³€κ²½ν•˜λŠ” 둜직이 λ‹΄κ²¨μžˆλŠ” ν•¨μˆ˜

// ν•΄λ‹Ή ν•¨μˆ˜μ—μ„œ 첫번째 인자인 stateλŠ” prevState(이전 state)λ₯Ό 의미
// action은 객체둜써 state에 μ‘°μž‘μ„ κ°€λ―Έν•˜λ €ν•˜λŠ” 객체
const reducer = (state, action) => {
  ...
  return newState;
}

dispatch

action 객체λ₯Ό λ„£μ–΄μ„œ μ‹€ν–‰

action

객체둜써 ν•„μˆ˜ ν”„λ‘œνΌν‹°λ‘œ type을 가진닀.

const click = () => {
  dispatch({ type: "PLUS" });
};


const reducer = (state, action) => {
  if (action.type === "PLUS") {
    return {
      count: state.count + 1,
    };
  }
  return state;
}

전체 μ½”λ“œ

import React, { useReducer } from "react";

const reducer = (state, action) => {
  if (action.type === "PLUS") {
    return {
      count: state.count + 1,
    };
  }
  return state;
};

const Example6 = () => {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  const click = () => {
    dispatch({ type: "PLUS" });
  };

  return (
    <div>
      <p>You clicked {state.count} times</p>
      <button onClick={click}>Click me!</button>
    </div>
  );
};

export default Example6;

πŸ“ useMemo

useMemo λ₯Ό μ‚¬μš©ν•˜λ©΄ ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈ λ‚΄λΆ€μ—μ„œ λ°œμƒν•˜λŠ” 연산을 μ΅œμ ν™” ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ¨Όμ € 배열에 μˆ«μžλ“€μ„ μΆ”κ°€ν•˜λ©΄ ν•΄λ‹Ή μˆ«μžλ“€μ˜ 합계λ₯Ό λ‚˜νƒ€λ‚΄λŠ” ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈλ₯Ό μž‘μ„±ν•΄λ΄…μ‹œλ‹€.

Before

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

const sum = (persons) => {
  console.log("sum...");
  return persons.map((person) => person.age).reduce((a, b) => a + b, 0);
};

const Example7 = () => {
  const [value, setValue] = useState("");
  const [persons] = useState([
    { name: "Mark", age: 39 },
    { name: "Hanna", age: 28 },
  ]);

  const change = (e) => {
    setValue(e.target.value);
  };

  // useMemoλ₯Ό ν™œμš©ν•©μ‹œλ‹€!
  const count = sum(persons);

  return (
    <div>
      <input value={value} onChange={change} />
      <p>{count}</p>
    </div>
  );
};

export default Example7;

μœ„μ²˜λŸΌ personsλΌλŠ” state 값에 μžˆλŠ” ageλΌλŠ” 값을 λ”ν•΄μ„œ λ Œλ”λ§ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€. μœ„ μ½”λ“œμ˜ λ¬Έμ œμ μ€ λ¬΄μ—‡μΌκΉŒμš”?

input의 λ‚΄μš©μ΄ λ°”λ€” λ•Œλ§ˆλ‹€ sumμ΄λΌλŠ” ν•¨μˆ˜κ°€ μœ„μ™€ 같이 계속 μ‹€ν–‰λ˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. persons의 값이 λ°”λ€Œμ§€λ„ μ•Šμ•˜λŠ”λ° ν•΄λ‹Ή sum ν•¨μˆ˜κ°€ κ³„μ†ν•΄μ„œ μ‹€ν–‰λ˜λŠ” 것은 낭비일 κ²ƒμž…λ‹ˆλ‹€.

useMemo Hook을 μ‚¬μš©ν•˜λ©΄ μ΄λŸ¬ν•œ μž‘μ—…μ„ μ΅œμ ν™” ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ Œλ”λ§ ν•˜λŠ” κ³Όμ •μ—μ„œ νŠΉμ • 값이 λ°”λ€Œμ—ˆμ„ λ•Œλ§Œ 연산을 μ‹€ν–‰ν•˜κ³  λ§Œμ•½μ— μ›ν•˜λŠ” 값이 바뀐 것이 μ•„λ‹ˆλΌλ©΄ 이전에 μ—°μ‚°ν–ˆλ˜ κ²°κ³Όλ₯Ό λ‹€μ‹œ μ‚¬μš©ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€.

μ½”λ“œλ₯Ό λ‹€μŒκ³Ό 같이 μˆ˜μ •ν•΄λ΄…μ‹œλ‹€.

After

const Example7 = () => {
  const [value, setValue] = useState("");
  const [persons] = useState([
    { name: "Mark", age: 39 },
    { name: "Hanna", age: 28 },
  ]);

  const change = (e) => {
    setValue(e.target.value);
  };

  // const count = sum(persons);

  const count = useMemo(() => {
    return sum(persons);
  }, [persons]);

  return (
    <div>
      <input value={value} onChange={change} />
      <p>{count}</p>
    </div>
  );
};

export default Example7;

μœ„μ™€ 같이 useMemoλ₯Ό ν™œμš©ν•˜λ©΄, dependency list에 값을 λ„£μ–΄μ£ΌλŠ” κ²ƒμ²˜λŸΌ λ‘λ²ˆμ§Έ 인자둜 λ³€ν•˜λŠ” 것을 감지할 값을 λ„£μ–΄μ£Όλ©΄ λ©λ‹ˆλ‹€. μ΄λ ‡κ²Œ 되면 μœ„μ™€ 같이 input의 λ‚΄μš©μ΄ λ°”λ€Œμ–΄λ„ sumμ΄λΌλŠ” ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜μ§€ μ•ŠλŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λ²ˆμ—λŠ” useReducer, useMemo에 λŒ€ν•΄ κ°„λ‹¨νžˆ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€. λ‹€μŒμ—λŠ” 여기에 더해 useCallbackκ³Ό useRef에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.πŸ“š

profile
Life is a matter of a direction not a speed.

0개의 λŒ“κΈ€