Redux 실습

현채은·2023년 4월 25일
0
post-thumbnail

💡 리덕스 구조 실습

Redux의 작동 순서

  • Action ➡️ Dispatch ➡️ Reducer ➡️ Store 순으로 작동함

✓ index.js

➡️ Store, Action, Reducer 구현

import React from 'react';
import {createRoot} from 'react-dom/client';
import {Provider} from 'react-redux';
import {legacy_createStore as createStore} from 'redux';
import App from './App'

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

// 🔹 Action 구현 (App.js 에서 사용하기 위해 export)
// 사용자가 버튼을 클릭했을때 발생되는 Action
export const increase = () => {
  return {
    type:'INCREASE'
  };
};

export const decrease = () => {
  return {
    type:'DECREASE'
  };
};

const count = 1;

// 🔹 Reducer 함수 구현

const createReducer = (state = count, action) => {
  switch(action.type) {
    case 'INCREASE':
      return state +1;
    case 'DECREASE':
      return state -1;
    case 'SET_NUMBER':
      return action.payload;
    defalut:
      return state;
  }
};
// 🔹Store 생성 (Reducer 함수를 인자로 넣어줌)
const store = createStore(createReducer);

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

✓ App.js

  • useDispatch() , useSelector 구현
import React from 'react';
import './style.css';
import {useSelector, useDispatch} from 'react-redux';
import {increase, decrease} from './index.js';

export default function App() {
  // useSelector() 구현
  const state = useSelector( (state) => state );
  console.log(state)
  
  //useDispatch() 구현
  // dispatch를 통해 Reducer 함수로 Action을 전달 
  const dispatch = useDispatch();
  
  const plusNum = () => {
    dispatch( increase() ); // 전달 인자로 Action 객체가 전달 됨
  };
  const minusNum = () => {
    dispatch( decrease() );
  }
  
  return (
    <div className = "container">
    	<h1>{`Count: ${state}`}</h1>
		<div>
		// + 버튼을 눌렀을 때 plusNum 호출
        <button className="plusBtn" onClick={plusNum}>
          +
        </button>
		// - 버튼을 눌렀을 때 minusNum 호출
        <button className="minusBtn" onClick={minusNum}>
          -
        </button>
      </div>
    </div>
  );
}

💡 리펙토링 실습

✓ index.js

import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import { Provider } from 'react-redux';
import { store } from './Store';

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

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

✓ App.js

import React from 'react';
import './style.css';
import { useSelector, useDispatch } from 'react-redux';
import { increase, decrease } from './Actions';

export default function App() {
  // useSelector() 구현
  const state = useSelector((state) => state);

  console.log(state);
  // useDispatch() 구현
  const dispatch = useDispatch();
  const plusNum = () => {
    dispatch(increase());
  };

  const minusNum = () => {
    dispatch(decrease());
  };

  return (
    <div className="container">
      <h1>{`Count: ${state}`}</h1>
      <div>
        <button className="plusBtn" onClick={plusNum}>
          +
        </button>
        <button className="minusBtn" onClick={minusNum}>
          -
        </button>
      </div>
    </div>
  );
}

🔹 Store/index.js

import {legacy_createStore as createStore} from 'redux';
import {counterReducer} from '../Reducer'

// store 생성
export const store = createStore(counterReducer);

🔹 Actions/index.js

  • Actions
    👉 type의 문자열을 변수화한 이유는 세가지 이유
    ①. 오타를 방지
    ②. 자동완성 기능을 통해 코드 생산성을 높일 수 있음
    ③. 코드를 재사용하기 용이
// Action은 다른 파일에서도 사용하기 때문에 export를 해줘야함
export const INCREASE = 'INCREASE'
export const DECREASE = 'DECREASE'

export const increase = () => {
  return {
    type: INCREASE,
  };
};

export const decrease = () => {
  return {
    type: DECREASE,
  };
};

🔹 Reducer/index.js

  • Reducer는 Dispatch에게서 전달받은 Action객체의 type 값에 따라서 상태를 변경시키는 함수
import {initalState} from './initialState.js'
import {INCREASE, DECREASE, increase, decrease} from '../Actions'

// Reducer 함수 구현

// initialState를 state로 사용
export const counterReducer = (state = initialState, action )=> {
  switch(Action.type){
    case INCREASE:
      return state +1;
    case DECREASE:
      return state -1;
    case 'SET_NUMBER':
      return action.payload;
    default:
      return state;
  }
};

🔹 Reducer/initialState.js

export const initialState = 1;
profile
프론트엔드 개발자

0개의 댓글