본문으로 바로가기

react-redux의 hook : useDispatch, useSelector

category State Management/⚛ Redux 2020. 6. 27. 20:47

react-redux 7버전 이후 부터 생긴 훅으로 인해 connect HOC를 사용하지 않아도 된다.

그러니까 전에 이런 걸 했는데 이제 이런 귀찮은 짓을 하지 않아도 된다는 것이다. 만세~~~

function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)

 

그렇다면 react-redux 훅을 하나씩 살펴보자

 

useDispatch

dispatch를 날리는 것입니다. 간단하죠!

아래 코드는 버튼을 눌릴 때마다 dispatch를 날립니다.

 

(https://react-redux.js.org/api/hooks#usedispatch)

 

dispatch의 값으로 action을 주면 됩니다.

import React from 'react'
import { useDispatch } from 'react-redux'
import { openLoginModalScreen } from "../reducers/global";

export const CounterComponent = ({ value }) => {
  const dispatch = useDispatch()

  return (
    <div>
      <span>{value}</span>
      <button onClick={() => dispatch(openLoginModalScreen)}>
        Increment counter
      </button>
    </div>
  )
}

 

 

useSelector

 

mapStateToProps의 역할과 비슷합니다. store에 저장된 state를 가져올 수 있는 역할입니다.

 

(https://react-redux.js.org/api/hooks#useselector)

import React from 'react'
import { useSelector } from 'react-redux'

export const CounterComponent = () => {
  const counter = useSelector(state => state.counter)
  return <div>{counter}</div>
}

 

그런데 해당 리덕스의 상태가 바뀌면 그 state를 사용하는 컴포넌트가 다시 렌더링됩니다. (컴포넌트는 스테이트가 바뀌면 재랜더링되죠.) 때문에 성능 최적화를 위해 useSelector를 아래와 같이 쪼개서 필요한 것만 가져오는 방식으로 

// user, isLoggedIn 둘 중 하나라도 바뀌면 재랜더링 됨
const {user, isLoggedIn} = useSelector((state) => state.user);


// 필요한 상태가 바뀔때만 재렌더링되게 다음과 같이 쪼개서 가져올 수 있음
// isLoggedIn만 가져오고 싶다면 다음과 같이 가져옵니다.
const isLoggedIn = useSelector((state) => state.user.isLoggedIn);

 

 

 

useDispatch와 useSelector 활용

 

useDispatch와 useSelector를 조합하여 다음과 같이 활용해보았습니다.

 

export default () => {
 
  const dispatch = useDispatch();
  
  // state 중 유저와 관련된 state를 가져옵니다.
  const user = useSelector((state) => state.user);
  
  // user와 관련된 reducer에서 도출된 state 값이 출력됩니다.
  // store에서 state를 가져온 것이니 사용하시면 됩니다.
  console.log(user);

  // useEffect 훅을 이용하여 dispatch를 날렸습니다.
  useEffect(() => {
    dispatch({
      type: LOG_IN,
      data: {
        nickname: "darren",
      },
    });
  }, []);
  
  // useSelector로 가져온 user 객체를 이용했습니다.
  // 변수명을 잘못 지은게 보이네요 user.user 라니... 하여튼 어쨋든 이런 방식으로 사용합니다.
  
    return (
    <>
      {user.isLoggedIn ? (
        <div>로그인했습니다: {user.user.nickname}</div>
      ) : (
        <div>로그아웃 상태입니다</div>
      )}
import { combineReducers } from "redux";
import user from "./user";
import post from "./post";

const rootReducer = combineReducers({
  user,
  post,
});

export default rootReducer;

darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체