Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

나를 위한 기록

[November 15] Redux설정, Store에서 값 읽어오기, useSelector / useDispatch 사용하기 본문

Today I Learned

[November 15] Redux설정, Store에서 값 읽어오기, useSelector / useDispatch 사용하기

솔솔이소리솔 2023. 11. 15. 19:02

redux 설정

1. src폴더 내에 redux폴더를 만들고 그 안에 config, modules 폴더를 생성한다.

2. config 폴더에 configStore.js를 생성한다.

3. configStore.js에서 중앙데이터 관리소(store)를 설정해준다.

 3-1. createStore와, combineReducers를 import한다.

import { createStore } from "redux";
import { combineReducers } from "redux";

 3-2. rootReducer를 만들어서 combineReducers를 넣어준다.

const rootReducer = combineReducers({
//modules에 넣어놓은 state의 묶음들을 이 객체 안에 몰아서 넣음!
// web application에서 관리하는 state의 집단들이 rootReducer로 들어오고
// 모든 컴포넌트 들은 props로 값을 내려주지 않더라도 
// 이 중앙 데이터 관리소로 데이터를 바라볼 수 있게 된다.
});

3-3. 만든 rootReducer로 store를 생성해주고, store를 외부로 export한다.

* 현재까지 configStore.js 셋팅

import { createStore } from "redux";
import { combineReducers } from "redux";

const rootReducer = combineReducers({

});
const store = createStore(rootReducer);

export default store;

4. index.js로 이동. strictMode 해제. Provider로 App Component 감싸주기.

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import store from "redux/config/configStore";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(  
  <Provider> //Provider는 아까 만든 Store를 기반으로 지배권을 행사함.
    <App />  // App이라는 Component가 Provider의 지배권 안으로 들어옴.
  </Provider>
);

reportWebVitals();

5-1. modules 안에 사용할 state(ex. counter.js)를 생성한다.

5-2. 초기 state를 설정하고 reducer 함수를 만든다. (아래 코드에서 counter가 reducer)

//초기 상태값(state)을 설정해준다.
const initialState = {
    number: 0
}
//위 형태는 useState사용시 const [number, setNumber] =useState(0);로 표현했었음.

//reducer = 'state에 변화를 일으키는'함수. state를 action의 type에 따라 변경한다.
//input 값으로  state와 action을 받는다.
const counter = (state = initialState, action) => {
// switch문을 통해서 action(객체형태)이 인자로 들어올 때 type과 value를 가지고 있음.
    switch (action.type) {
        // action.type에 따라 작업을 수행한다.
        default:
            return state;
            //아무 것도 없을 때는 initialState를 return한다.
    }
}
export default counter;

6-1. configStore.js에 위에서 만들어 둔 reducer를 import한다.

6-2. rootReducer안에 import한  reducer를 key, value 쌍으로 넣어준다.

useSelector 사용하기

7. App.js에서 store에 접근하여 modules 안에 있는 reducer(예시에서 counter)를 읽어오기 위해 useSelector를 사용한다.

 7-1. useSelector를 import해준다.

 7-2. uesSlector 함수 안에 state를 인자로 넣어주고 state.counter로 reducer의 값을 가져온다.

*App.jsx

import "./App.css";
import Router from "./shared/Router";
import { useSelector } from "react-redux";

function App() {
//  여기에서 store에 접근하여, counter의 값을 읽어오고 싶다!
// useSelector 훅 사용!
  const data = useSelector((state) => {
  		return state.counter
  });
  return <Router />;
}
export default App;

 

정리
: Store 안에는 State(전역상태)와 Reducer(제어)가 있다.

Reducer가 State를 제어할 때는 Switch문을 통해 action객체의 type (switch(action.type) 형태)에 따라 동작하게 한다.

 

useDispatch 사용하기

만약 UI(컴포넌트)에서 어떤 이벤트가 발생하여 Store에 있는 counter라는 값을 변경해야한다는 요청이 일어나면,

(ex. button 클릭 시 onClick 이벤트가 발생하여 state 값을 바꾸는 경우) Dispatch가 그 요청을 수행한다. 

 

Dispatch는 UI에서 일어난 요청을 action객체로 Store에 던져주고 Store는 action의 type에 따라 State를 변경한다.

예제. + 버튼 클릭시 카운트가 1씩 늘어나도록 state를 변경하고 화면에 표시하기.

1. 먼저 App.jsx에 UI를 만들어 준다.

import "./App.css";
import Router from "./shared/Router";
import { useSelector } from "react-redux";

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

  return (
    <>
      <div>현재 카운트: {counter.number}</div>
      <button onClick={()=> {
     		//+1 하는 로직이 여기에 들어감.
      }}>+</button>
    </>
  );
}

export default App;

2. counter.js에 type에 따라 어떻게 state를 변경할 것인지 설정해준다.

const counter = (state = initialState, action) => {
    switch (action.type) {
        case "PLUS_ONE":
            return {
            // state가 {number: 0}형태이므로 객체형태로 리턴한다.
                number: state.number + 1,
            }
        default:
            return state;
    }
}

  3. 이제 App.jsx 에서 action 객체를 PLUS_ONE으로 던져주면 된다.

action객체를 Store로 던져주는 역할을 하는 Dispatch를 여기서 사용한다.

4. App.jsx에 Dispatch 가져오기.

 4-1. dispatch 함수를 선언해주고 useDispatch import

 4-2. onClick 이벤트 핸들러 함수에 dispatch를 넣어준다. + dispatch의 인자로 type: "PLUS_ONE"을 넘겨준다.

import "./App.css";
import Router from "./shared/Router";
import { useDispatch, useSelector } from "react-redux";

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

  //Dispatch 가져와보자!
  const dispatch = useDispatch()

  return (
    <>
      <div>현재 카운트: {counter.number}</div>
      <button onClick={()=> {
        dispatch({
          type: "PLUS_ONE",
        })
      }}>+</button>
    </>
  );
}
export default App;