본문 바로가기

React/상태관리하기

Redux React에 적용하기

앞서 게시한 Redux 정리를 기반으로 React에 적용하는 방법을 정리하도록 하겠습니다.

 

 

 

Redux 정리

Redux 란? Redux는 Cross-Component-State 또는 앱 와이드 상태를 위한 상태 관리 시스템으로 애플리케이션을 변경하며 브라우저에 표시하는 데이터를 다수의 컴포넌트나 심지어는 앱 전체에서 관리하도

nicehyun12.tistory.com

 

 

 

 Redux React에 적용 

초반 Redux 설정은 앞서 게시한 Redux 정리(NodeJS)한 절차와 거의 동일함으로 간략한 코드 예시만 첨부하도록 하겠습니다.

 

 

npm i redux

npm i react-redux

작업 전 Redux 라이브러리와 React와 Redux를 간편하게 연결해주는 라이브러리를 설치해줍니다.

 

 

우선 Redux 로직을 별도의 파일에 관리하기 위해 별도의 볼더와 파일을 하나 생성해줍니다.

(store 폴더에 있는 index.js 파일에 로직을 작성할 예정입니다.)

 

 

다음으로 Redux 초기 설정을 해주도록 하겠습니다.

// 리덕스 로직을 저장

// 0. redux import
import { createStore } from "redux";

// 2. Reducer 함수 생성 후 Action에 대한 작업 설정 - State의 초깃값 설정 필수 
// (Reducer 함수는 항상 객체를 새로운 반환하고 반환된 객체는 store에 저장)
const countReducer = (state = { counter: 0 }, action) => {
  if (action.type === "INCREMENT") {
    return { counter: state.counter + 1 };
  }

  if (action.type === "DECREMENT") {
    return { counter: state.counter - 1 };
  }

  return state;
};

// 1. store(중앙 데이터 저장소) 생성
// 3. store과 Reducer 함수 연결
const store = createStore(countReducer);

// 4. React에서 Redux store에 접근할 수 있도록 설정
export default store;

순서를 정리해보면

0. Redux를 import 해줍니다.

1. store(중앙 데이터 저장서)를 생성해줍니다.

2. Reducer 함수를 생성해주고 전달받을 각 Action에 대한 작업을 설정해줍니다. (초기 State 설정은 필수입니다.)

3. store과 Reducer 함수를 연결해줍니다.

4. Redux store(중앙 데이터 저장소)와 React를 연결할 수 있도록 설정해줍니다.

(이렇게 연결해주어야 컴포넌트에서 store에 dispatch(Action 전달)가 가능하게 됩니다.)

 

(게시한 Redux 정리에서는 파일 내부에서 dispatch 메서드를 사용하여 Action을 Redux에 전달했지만 React에서는 컴포넌트 내부에서 Action을 전달하기 때문에 Redux 로직 파일에서 Action을 전달 작업을 따로 하지 않습니다.)

 

 

Redux store(중앙 데이터 저장소)와 React를 연결하기 위해 주로 React의 최상위 루트인 index.js 파일에서 연결 작업을 진행합니다.

 

(store는 항상 단 하나만 사용하기 때문에 App 전체에서 사용하기 위해서 최상위 루트에서 연결 작업을 진행합니다.

무조건 최상위 루트에서 연결 작업을 할 필요는 없지만 보통 애플리케이션 전체에서 store에 접근을 하기 때문에 최상위 루트에서 연결합니다. 이는 Provider 컴포넌트로 감싸진 컴포넌트에서만 store에 접근이 가능하기 때문입니다.)

앞서 설치한 react-redux 라이브러리에서 Provider 컴포넌트를 import 해줍니다.

(해당 라이브러리를 통해 React는 Redux의 store에 쉽게 접근이 가능하게 됩니다.)

 

다음으로 import 한 Provider 컴포넌트로 App 컴포넌트 감싸줍니다.

(Provider 컴포넌트는 React-Context의 Provider와 같은 기능을 합니다.)

 

다음으로 앞서 생성한 Redux store을 import 해주고 Provider 컴포넌트의 prop으로 전달합니다.

 

 

여기까지 진행되면 Provider 컴포넌트의 자식 컴포넌트에서는 store에 Subsciption 설정이 가능하여 State에 접근이 가능하며, dispatch(Action 전달)가 가능하게 됩니다.

 

 

아래의 컴포넌트는 Redux store에 저장된 State를 사용할 컴포넌트입니다.

Counter.js
import classes from "./Counter.module.css";

const Counter = () => {
  const toggleCounterHandler = () => {};

  return (
    <main className={classes.counter}>
      <h1>Redux Counter</h1>
      <div className={classes.value}>-- COUNTER VALUE --</div>
      <button onClick={toggleCounterHandler}>Toggle Counter</button>
    </main>
  );
};

export default Counter;

 

 

해당 컴포넌트에서 react-redux 라이브러리에서 useSelector hook을 import 해줍니다.

(useSelector hook을 사용하면 store에 저장된 State의 일부를 쉽게 선택할 수 있습니다.)

 

그런 다음 컴포넌트 내부에서 useSelector hook을 호출하여 인수로 함수를 전달해줍니다.

 

전달하는 함수는 어떤 State를 store에서 추출할 것인지를 결정하는 역할을 하며, 인수로는 store에서 관리하는 State를 전달받고 State의 일부를 추출하여 반환하게 됩니다.

(이때 useSelector hook에 전달되는 함수는 react-redux 라이브러리에서 실행시켜 자동으로 State의 일부를 반환받을 수 있게 됩니다.)

 

즉 상수 counter은 Redux가 관리하는 store에 저장된 State의 일부인 counter를 저장하게 됩니다.

 

또한 useSelector hook을 사용하면 react-redux 라이브러리가 자동으로 Subscription 설정을 해주기 때문에 추출한 State의 값이 변하게 되면 해당 컴포넌트는 업데이트가 됩니다.

 

 

이제 컴포넌트가 store에 저장된 State 값을 사용하기 위해 Subscription 설정이 되었기 때문에 사용 또한 가능하게 됩니다.

 

 

다음으로 Action을 Redux에 전달해주어 store에 저장된 State를 Reducer 함수가 변경할 수 있게 해주어야 합니다.

우선 증가 버튼과 감소 버튼을 추가하고 각각의 버튼을 클릭했을 때 dispatch 작업(Redux에 Action을 전달)을 하기 위해 useDispatch hook을 import 해줍니다.

 

dispatch 함수는 인수로 전달받는 Action을 Redux에 전달하게 됩니다.

 

때문에 dispatch(Action이 증가, 감소)하는 각각의 함수를 생성하여 버튼에 전달하도록 합니다.

 

이렇게 증가 버튼을 클릭하면 store에서 추출한 counter 변수가 증가하게 되고 해당 컴포넌트의 UI가 변경되게 됩니다.

 

 

정리

useSelector hook을 사용하면 store에 저장된 State 일부에 쉽게 접근하여 사용할 수 있고 추가로 Subscription 작업이 자동으로 됩니다.

 

store에 저장된 State를 변경하기 위해 useDispatch hook을 사용하였으며 useDispatch hook은 전달받은 액션을 dispatch가 가능하도록 합니다