[React]Hooks - useReducer, useMemo

yujo·2020년 7월 29일
0

React

목록 보기
3/5
post-thumbnail

useReducer

useReduceruseState보다 더 다양한 상황에 따라 다양한 상태를 다른 값으로 업데이트 하고 싶을 때 사용하는 Hook입니다. 리듀서는 현재 상태, 그리고 업데이트를 위해 필요한 정보를 담은 액션값을 전달받아 새로운 상태를 반환하는 함수입니다. 리듀서 함수에서 새로운 상태를 만들 때는 반드시 불변성을 지켜야 합니다.

function reducer(state, action) {
  return { ... };
}

useReducer 사용하기

아래는 useReducer를 사용하여 Counter 컴포넌트를 구현한 모습입니다.

import React, { useReducer } from "react";

function reducer(state, action) {
  switch (action.type) {
    case "INCREMENT":
      return { value: state.value + 1 };
    case "DECREMENT":
      return { value: state.value - 1 };
    default:
      return state;
  }
}

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

  return (
    <div>
      <p>
        Current counter value is <b>{state.value}</b>
      </p>
      <button onClick={() => dispatch({ type: "INCREMENT" })}>+1</button>
      <button onClick={() => dispatch({ type: "DECREMENT" })}>-1</button>
    </div>
  );
};

export default Counter;

이와 같이 useReducer를 사용하면 컴포넌트 업데이트 로직을 컴포넌트 바깥으로 빼낼 수 있다는 장점이 있습니다.

useReducer input 관리하기

useState를 사용할 경우 인풋이 여러개일 때는 여러개의 useReducer를 사용해야 했습니다. 하지만 useReducer를 사용하면 input 태그에 name 값을 할당하고 e.target.name을 참조하여 setState를 해준 것처럼 작업을 처리할 수 있습니다.

import React, { useState, useEffect, useReducer } from "react";

function reducer(state, action) {
  return {
    ...state,
    [action.name]: action.value,
  };
}

const Info = () => {
  const [state, dispatch] = useReducer(reducer, {
    name: "",
    nickname: "",
  });

  const { name, nickname } = state;
  const onChange = (e) => {
    dispatch(e.target);
  };

  return (
    <div>
      <div>
        <input name="name" value={name} onChange={onChange} />
        <input name="nickname" value={nickname} onChange={onChange} />
      </div>
      <div>
        <div>
          <b>name:</b> {name}
        </div>
        <div>
          <b>nickname:</b> {nickname}
        </div>
      </div>
    </div>
  );
};

export default Info;

useMemo

useMemo를 사용하면 함수형 컴포넌트 내부에서 발생하는 연산을 최적화할 수 있습니다.

useMemo 사용하기

useMemo를 사용하면 렌더링 과정에서 특정 값이 바뀌었을 때만 연산을 실행하고, 원하는 값이 바뀌지 않았다면 이전에 연산했던 결과를 다시 사용합니다.

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

const getAverage = (numbers) => {
  console.log("Loading ...");
  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}>CHECK</button>
      <ul>
        {list.map((value, index) => (
          <li ket={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>Average : </b> {avg}
      </div>
    </div>
  );
};

export default Average;

profile
@42seoul

0개의 댓글