개발 공부/React / / 2022. 10. 27. 13:07

[React] Redux 예제 - 버튼 눌러서 값 변경하기

Redux : Node.js 모듈. JavaScript 상태 관리 라이브러리 

Redux Flow 이미지 출처: www.google.com  

 

[예제] 위의 플로우처럼 초기값 0에서 버튼을 눌러 더하고 뺀 값을 UI에 반영하기 

 

디렉토리 구조 

1. Redux 설치 

react에서 redux를 사용하기 위해서는 redux, react-redux를 설치해야한다.

npm install redux
npm install react-redux

2. src>store디렉토리 생성 후 안에 store.js 생성

src/store/store.js 안에 아래 3개의 코드를 넣어준다

 

-  Action 만들기

state에 변화를 일으킬 때 참조하는 객체. 버튼이 눌리면 dispatch를 통해 action을 생성한다. action은 반드시 type이 존재해야 한다.

 

// Actions
const INCREMENT = "INCREMENT";
const DECREMENT = "DECREMENT";

// Action Creator
export const increment = () => {
    return {
        type: INCREMENT,
    };
}
export const decrement = () => {
    return {
        type: DECREMENT,
    };
}

- state 초기값 설정 

// 초기값 설정
const initialState = {
  number: 0,
};

- reducer 생성

// counterReducer
export default function counter(state = initialState, action) {
  switch (action.type) {
    case INCREMENT:
      return {
        number: state.number + 1,
      };
    case DECREMENT:
      return {
        number: state.number - 1,
      };
    default:
      return state;
  }
}

store.js 전체 코드 

// Actions
const INCREMENT = "INCREMENT";
const DECREMENT = "DECREMENT";

// Action Creator
export const increment = () => {
    return {
        type: INCREMENT,
    };
}
export const decrement = () => {
    return {
        type: DECREMENT,
    };
}

// 초기값 설정
const initialState = {
    number: 0,
};

// counterReducer
export default function store(state = initialState, action) {
    switch (action.type) {
        case INCREMENT:
            return {
                number: state.number + 1,
            };
        case DECREMENT:
            return {
                number: state.number - 1,
            };
        default:
            return state;
    }
}

3. combineReducer 생성

참고 문헌에 있던거라 사실 정확이 어떤 건지는 잘 모른다. 리듀서를 합치는 기능이라고 한다. 프로젝트가 커지는 경우 사용한다고. 위에서 만든 store.js를 import 해준다.

src>store>combine_reducer.js

import { combineReducers } from "redux";
import store from "./store";

// import한 리듀서 이름을 그대로 사용하는 경우
export default combineReducers({
    counter: store,
});

// // 리듀서 이름을 지정하는 경우
// export default combineReducers({
//     // 리듀서 이름: import한 리듀서
//     counterData: store,
// });

4. index.js에서 Redux 설정

- import 해주기 

//redux
import { createStore } from "redux";
import { Provider } from "react-redux";
import rootReducer from "./store/combine_reducer";

- createStore 추가

//redux
const store = createStore(rootReducer);

- <Provider>로 감싸주기

<React.StrictMode>
      <Provider store={store}>
    <App />
      </Provider>
  </React.StrictMode>

index.js 전체 

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import { createStore } from "redux";
import { Provider } from "react-redux";
import rootReducer from "./store/combine_reducer";

const root = ReactDOM.createRoot(document.getElementById('root'));
const store = createStore(rootReducer);

root.render(
  <React.StrictMode>
      <Provider store={store}>
    <App />
      </Provider>
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

5. 따로 Component를 생성하거나 사용할 Component안에 에 코드 넣기 

참고 문헌에서는 따로 Component를 생성했는데 나는 이미 만들어 둔 게 있어서 Main.js에 넣었다 

추가할 코드 

//redux
import { useDispatch, useSelector } from "react-redux";
import { decrement, increment } from "../store/store";

const dispatch = useDispatch();

// import한 리듀서 이름을 그대로 사용하는 경우
const count = useSelector((state) => state.counter.number);


 <h1>COUNTER</h1>
      <h4>{count}</h4>
      <br />
      <button onClick={() => dispatch(increment())}> + </button>
      <button onClick={() => dispatch(decrement())}> - </button>

적용된 코드 

...

import { useDispatch, useSelector } from "react-redux";
import { decrement, increment } from "../store/modules/counter";

const Main = () => {

export default function Counter() {

    const dispatch = useDispatch();
    const count = useSelector((state) => state.counter.number);
  
   return (
        <div className={"test"}>
            <Box sx={{
                marginTop: 8,
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center'
            }}>

                <div>
                    <div>

                     ...
                     
                        <h1>COUNTER</h1>
                        <h4>{count}</h4>
                        <br />
                        <button onClick={() => dispatch(increment())}> + </button>
                        <button onClick={() => dispatch(decrement())}> - </button>
                    </div>

                </div>

            </Box>
        </div>
    )
}
export default Main;

npm start로 프로젝트 실행 화면

 

 

 

참고 문헌 

https://ivorycode.tistory.com/entry/Redux%EC%9D%98-%ED%9D%90%EB%A6%84%EA%B3%BC-%EC%98%88%EC%A0%9C

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유