조금조금 REACT, ReDUX

Edwin·2023년 3월 4일
0

조금조금 REACT

목록 보기
16/31
post-thumbnail

조금조금 REACT, ReDUX

리덕스란 리액트 환경에서 사용하는 외부 라이브러리(패키지)이다. 이를 사용하는 이유는 state 변경을 다루는 상태관리를 보다 효율적으로 관리하기 위해서였다.

이전에 useContext를 통해서 상태관리를 제어하는 부분도 살펴보았지만, useContext가 동작하는 부분에 있어서 상태가 변경될 때마다 리렌더링 된다는 측면의 한계와 여러가지 이유에서 확장 프로그램이라고 볼 수 있는 리덕스가 등장하게 되었다.

상태관리의 정점 : REDUX

1) yarn으로 설치하기

yarn add redux react-redux

2) REDX 환경설정

리덕스를 활용하기 위해서는 우리의 폴더를 리덕스가 동작하는 환경으로 구성해주어야 할 필요가 있다.

create react-app > src

create react-app로 생성된 폴더에 아래와 같이 추가해준다.

src >> redux 폴더

  • config 폴더 >> configStore.js
  • modues 폴더
  • redux : 리덕스 관련 폴더/파일의 최상위 폴더
  • config : 리덕스 설정 관련 파일이 담기는 폴더
  • config > configStore.js : 중앙데이터 관리소(설정 코드(.js))
  • modues : Redux 안에서 관리할 state 관련폴더

3) configStore.js 설정하기

import { createStore } from "redux";
import { combineReducers } from "redux";
import users  from "../modules/uesers";
 
import counter from "../modules/counter";
 
const rootReducer = combineReducers({
  counter, users
})

const store = createStore(rootReducer);

위의 코드는 modules 폴더 안에 counter.js, users.js가 각각 있다는 전제에서 보아야 한다.

먼저 전역에서 사용할 저장소를 사용하기 위해서는 두 가지를 임포트 해야 한다.

  • createStore : 저장소를 생성하는 것
  • combineReducers : 모듈에 있는 리듀서함수들을 통합하기 위한 것

createStore

const store = createStore(rootReducer);
export default store;

createStore를 임포트 했다면, 생성해야 하는데 위와 같은 코드를 선언함으로 전역에서 사용할 저장소를 생성할 수 있다. 그리고 만들어진 저장소를 export 시켜서 사용할 수 있는 준비를 설정해준다.

combineReducers

const rootReducer = combineReducers({
  counter, users
})

modules 폴더 안에 선언된 state 관련 리듀서 함수들을 combine(하나로 결합)하여 rootReducer란 식별자 안에 담아준다.

4) 각각의 module에서 사용하기

counter.js

const initialState = {
  number:0
}

const counter = (state = initialState, action) => {
  switch (action.type) {
    case "plusCounter" : 
      return {
        number : state.number+1
      }
    case "minusCounter" : 
      return {
        number : state.number-1
      }  
    default:
      return state
  }
}

export default counter;

state 생성하기

저장소로 보낼 내용을 아래와 같이 선언한다.

const initialState = {
  number:0
}
//  useState에서 선언했던 : const [number, setNumber] = useState(0) 와 동일

리듀서함수 생성하기

const counter = (state = initialState, action) => {
  switch (action.type) {
    case "plusCounter" : 
      return {
        number : state.number+1
      }
    default:
      return state
  }
}
  • 리듀서 함수의 매개변수1 : state = initialState
    저장소에서 가져 올 state(상태)가 무엇인지 선언하는데, initialState에서 볼 수 있듯이, 바로 위에서 생성한 {number}이다.
  • 리듀서 함수의 매개변수2 : 해당 함수에서 사용할 action이 무엇인지에 대해서 선언하고 있다. 여기서 action은 어디에서 정의가 된 것일까?

전역저장소와 리듀서 사용하기 : App.jsx

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

function App() {
  const counter = useSelector((state)=>{
    return state.counter
  });
  const dispatch = useDispatch();

  return (
    <div>
      {counter.number} <br />
      <button onClick={()=>{dispatch({type:"plusCounter",})}}>더하기</button>
      <button onClick={()=>{dispatch({type:"minusCounter",})}}>더하기</button>
    </div>
  )
}

export default App

Redux를 사용하기 위해서는 두 가지를 먼저 import 해야 한다.

  • useDispatch : 리듀서 함수를 사용하기 위해서
  • useSelector : 전역저장소를 사용하기 위해서

먼저, useSelector을 통해서 전역저장소(configStore.js)에서 값을 가져와야 한다. 해당 부분이 const counter = useSelector이다. 모듈에서 생성한 number를 가져와서 이렇게 사용할 수 있게 되는 것이다.

둘째, useDispatch를 통해서 dispatch함수를 사용할 준비를 한다.

셋째, 이제 실행이다. <button onClick={()=>{dispatch({type:"minusCounter",})}}>와 같이 기록해주면 된다. dispatch는 action을 호출하는데, type으로 minusCounter"를 선언하였다.

모듈로 돌아가서 counter 함수 실행

const counter = (state = initialState, action) => {
  switch (action.type) {
    case "plusCounter" : 
      return {
        number : state.number+1
      }

dispatch는 action.type = "plusCounter"에 대해서 해당 리듀서 함수는 state(전역저장소)와 연결지은 해당 모듈에서 선엉한 initialState을 가져올 것이다. >> return 문을 보면 {initialState객체}를 변경해 주는 것인데, number(key)에 기존 state.number(initialState.number)에 1을 더한 값으로 변경해 주는 것이다.

그 결과 만약 App.jsx 의 본문 부분에서 {counter.number} 를 선언했다면, counter모델의 number가 즉시 변경되며 화면에 표현되는 것을 볼 수 있을 것이다.

5) 정리하기

리액트 공식사이트에서 설명한 이미지

첫째, 전역저장소(configStore.js)에 각각의 모듈들이 저장되어 있다. 해당 함수들이 store란 이름으로 밖으로 배출되었고, 이를 가져다 사용하는 어떤 컴포넌트라도 이를 사용할 준비가 된 것이다.

UI(App.js)에서 해당 저장소를 사용하기 위해서 상단에 useSelector 를 임포트해주고

const counter = useSelector((state)=>{
    return state.counter
  })

저장소에서 가져와서 사용할 counter 식별자를 생성해준 것이다. 그리고 이를 {counter.number} 를 통해서 화면에 기록해 주었다고 하자. 이 부분이 이해하기 어려운 부분인데, useSelector을 통해서 > 전역저장소(configStore.js)의 state.counter이 선택되었고 > 전역저장소(configStore.js)는 combineReducers으로 연결된 rootReducer 가운데 counter를 UI로 가져온 것이다. 여기서 state는 전역객체 combineReducers에 있는 객체에 대한 이름인 것이다.

둘째, 그리고 역시 UI(App.js)에서 useSelector 를 통해서 연결된 모듈의 dispatch를 실항하는 버튼을 UI에서 클릭하면 > dispatch는 action.type을 가지고 모듈로 이동해서 > 해당 type에 따른 switch문에 따라 정보를 변경 > 이 과정이 모두 전역저장소(configStore.js)에서 관리되고 있기에 > UI에서 선언한 {counter.number}**, 전역저장소를 기준으로 하면 {state.counter.number} 즉시로 해당 변경 정보를 적용시켜 주는 것이다.

여기까지가 Redux에 대한 선이해에 해당된다. 이를 다루며 더 심층으로 나아가보자.

Editor. EDWIN
date. 23/03/04

profile
신학전공자의 개발자 도전기!!

0개의 댓글