React 입문 - react-redux 리덕스 사용법

2023. 1. 4. 22:33React 공부

728x90
SMALL
나를 위한 리덕스 사용법 정리

 

리덕스를 사용하려면 2개의 패키지를 설치해야한다.

  • 명령어
yarn add redux react-redux

redux 와 react-redux를 한번에 설치한다.

폴더생성

 

 

▶️ configStore.js 파일  // 기본 코드

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

/*
1. createStore()
리덕스의 가장 핵심이 되는 스토어를 만드는 메소드(함수) 입니다. 
리덕스는 단일 스토어로 모든 상태 트리를 관리한다고 설명해 드렸죠? 
리덕스를 사용할 시 creatorStore를 호출할 일은 한 번밖에 없을 거예요.
*/

/*
2. combineReducers()
리덕스는 action —> dispatch —> reducer 순으로 동작한다고 말씀드렸죠? 
이때 애플리케이션이 복잡해지게 되면 reducer 부분을 여러 개로 나눠야 하는 경우가 발생합니다. 
combineReducers은 여러 개의 독립적인 reducer의 반환 값을 하나의 상태 객체로 만들어줍니다.
*/

const rootReducer = combineReducers({}); 
const store = createStore(rootReducer); 

export default store;

 

 

▶️ index.js 파일  // 기본 코드

// 원래부터 있던 코드
import React from "react";
import ReactDOM from "react-dom/client";
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(

	//App을 Provider로 감싸주고, configStore에서 export default 한 store를 넣어줍니다.
  <Provider store={store}> 
    <App />
  </Provider>
);

// 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();

카운터 프로그램으로 리덕스 익혀두기

 

▶️ counter.js 파일  // modules 폴더안에 생성

// src/modules/counter.js

// 초기 상태값
const initialState = {
  number: 0,
};

// 리듀서
const counter = (state = initialState, action) => {
  switch (action.type) {
    default:
      return state;
  }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default counter;

module은 state의 그룹이다.

 

초기값에 대한 코드를 살펴보자.

const initialState = {
  number: 0,
};

// 리덕스 초기값 입력 코드


const [value, setValue] = useState(0);

// 리액트 기본 초기값 입력 코드

위 코드와 아래 코드 동일한 코드이며, 리덕스에서는 위의 코드를 사용하면 된다.

 

다음으로는 리듀서에 대한 설명이다.

const counter = (state = initialState, action) => {
  switch (action.type) {
    default:
      return state;
  }
};

리듀서는 변화를 일으키는 함수이다.

 

우리가 리액트에서 useState를 사용할때 number를 바꾸고 싶다면 setNumber를 사용했었다.

const onClickHandler = () => {
	setNumber(number+1)
}

위 처럼 setNumber를 쓰고 안에 변화를 주는 형식으로 사용했었다.

리덕스에서는 리듀서가 위와 같은 역할을 한다.

리덕스는 리듀서를 포함한 스토어라고 할 수 있다.
스토어는 상태를 저장하는 장소이다.
우리가 어떤 액션을 일으키는 것을 디스패치라 하고
액션을 일으켰을때 리듀서가 자동 실행된다.
그리고 그 액션에 맞게 데이터를 수정해준다.
즉, 스토어에 있는 데이터를 바꿔주는 역할을 리듀서가 한다.

 

 

작성한 모듈을 스토어에 연결을 해줄 차례이다.

import { createStore } from "redux";
import { combineReducers } from "redux";
import counter from "../modules/counter"

/*
1. createStore()
리덕스의 가장 핵심이 되는 스토어를 만드는 메소드(함수) 입니다. 
리덕스는 단일 스토어로 모든 상태 트리를 관리한다고 설명해 드렸죠? 
리덕스를 사용할 시 creatorStore를 호출할 일은 한 번밖에 없을 거예요.
*/

/*
2. combineReducers()
리덕스는 action —> dispatch —> reducer 순으로 동작한다고 말씀드렸죠? 
이때 애플리케이션이 복잡해지게 되면 reducer 부분을 여러 개로 나눠야 하는 경우가 발생합니다. 
combineReducers은 여러 개의 독립적인 reducer의 반환 값을 하나의 상태 객체로 만들어줍니다.
*/

const rootReducer = combineReducers({
	 counter: counter,
 }); 
const store = createStore(rootReducer); 

export default store;

configStore.js에 가서 모듈을 임포트해준다.

우리가 넣을 모듈 이름은 counter.js 파일을 적용시켜준다.

import counter from "../modules/counter"

import 모듈이름 from 모듈경로

임포트를 하고난 뒤

rootReducer 부분에 임포트한 모듈을 넣어주면 된다.

const rootReducer = combineReducers({ });

위에 있던 코드에서 아래 코드로 바뀐것을 알 수 있다. ( counter를 추가해줬다.)

const rootReducer = combineReducers({
	 counter: counter,
 });

이렇게 하면 스토어와 모듈이 연결된다.

프로젝트를 하면서 모듈이 하나씩 생길때마다 지금과 같은 방법으로 스토어에 하나씩 연결하면 된다.

 

여기까지 진행 했다면 연결이 잘 된것이 확인해 볼 필요가 있다.

컴포넌트에서 스토어를 직접 조회하면 되는데 useSelector를 이용해서 확인할수 있다.

// src/App.js

import React from "react";
import { useSelector } from "react-redux"; // import 해주세요.

const App = () => {

  return <div></div>;
}

export default App;

위 코드에는 import {useSelector} from "react-redux"; 가 적혀있다. 임포트 하는 것 잊지말자!

// src/App.js

import React from "react";
import { useSelector } from "react-redux"; // import 해주세요.

const App = () => {
	const counterStore = useSelector((state) => state);
	console.log(counterStore);
  return <div></div>;
}

export default App;

콘솔로그로 찍어봤을 때 state값이 잘 나오는 것을 확인 할 수 있다.

이렇게 화살표함수에서 꺼낸 state인자는 현재 프로젝트에서 존재하는 모든 redux 모듈의 state를 가져온다.

number라는 값만 꺼내 오려면 아래 코드와 같이 입력하면 된다.

const number = useSelector((state) => state.counter.number);

위 코드를 counterStore 아래에 넣어주면 된다.

state.counter.number는

state안에 카운터를 찾고 그 다음에 카운터 안에 있는 넘버를 찾으라는 말이다.

// src/App.js

import React from "react";
import { useSelector } from "react-redux"; // import 해주세요.

const App = () => {
	const counterStore = useSelector((state) => state);
    	const number = useSelector((state) => state.counter.number);
	console.log(counterStore);
   	console.log(number);
    
  return <div></div>;
}

export default App;

이렇게해서 콘솔로그(넘버)를 찍어보면 이와 같이 나오게 된다.

 맨 아래에 숫자 0이 잘 찍힌 것을 볼 수 있다.

 

* 지금까지 내용정리 💡

모듈은 기능의 이름을 따서 파일을 생성한다.
모듈의 구성요소는 initialState, reducer가 있다.

모듈을 만들면 store에 연결해야한다.

그리고 컴포넌트로 가서 스토어를 연결해줘야한다.
store를 조회할때는 useSelector를 사용해야한다.

useSelector(state)는 모든 모듈에서 state를 조회할 수 있는 값이다.

 


localState였던 useState에서 setState 하나면 알면 됐지만
redux에서는 dispatch, reducer 이런 중간 단계가 많다.

위 그림을 참고하여 리덕스가 어떤 흐름인가 알아둘 것.

  1. View 에서 액션이 일어난다.
  2. dispatch 에서 action이 일어나게 된다.
  3. action에 의한 reducer 함수가 실행되기 전에 middleware가 작동한다.
  4. middleware 에서 명령내린 일을 수행하고 난뒤, reducer 함수를 실행한다. (3, 4번은 아직 몰라도 됩니다!)
  5. reducer 의 실행결과 store에 새로운 값을 저장한다.
  6. store의 state에 subscribe 하고 있던 UI에 변경된 값을 준다.

출처 : https://velog.io/@annahyr/리덕스-흐름-이해하기

 

store에 있는 값을 변경하는 방법

먼저 리액트에서는 아래와 같은 코드로 넘버값을 변경해 주었다.

// local state
const [number, setNumber] = useState(0)


// click handler
const onClickHandler = () => {
	setNumber(number + 1)
}

 리덕스에서는 값은 리듀서에서 일어난다.
모듈에 있는 넘버에 더하기 1을 하고 싶으면 리듀서에 보낼 명령을 만든다. 그 명령은 number +1 이다.
명령을 보내면 리듀서에서 그 명령을 받고 number +1을 한다.

 

전역상태라는 것은 변경값을 어느 컴포넌트에서나 쉽게[ 접근해서 조회할 수 있고 그 값을 변경하는 것도 쉬워진다.
  • 리듀서 : 변화를 일으키는 함수이다.
  • 액션 : 변경하라고 명령하는 것을 말한다.
  • 액션객체 : 변경하라고 명령하는 것을 코드로 표현한 것을 말한다.

* 참고로 액션객체에는 반드시 type 이라는 키가 있어야한다.

 

// src/App.js

import React from "react";
import { useSelector } from "react-redux"; // import 해주세요.

const App = () => {
	
    
  return 
  	<div>
        <button>
        +1
        </button>
    </div>;
}

export default App;

 return에 버튼을 생성했다.
( 참고로 아까 적었던 useSelector들은 조회가 잘되나 보기위해 생성했던 코드이고, 조회가 잘 되는지 확인을 마쳤기때문에 지웠다.)

버튼 생성을 했으니 이제 리듀서에 number +1 을 하라고 명령을 보내야 한다.
명령을 보내기전 리듀서가 해당 명령을 받을 수 있도록 만들어줘야한다.

 

액션(명령)을 하기 전에 useDispatch라는 Hook을 사용해야한다.
그러기 위해서는 useDispatch를 임포트 해줘야한다. (* 어떤 작업을 할때마다 임포트하는 과정을 잊지않도록 주의해야겠다.)

// src/App.js

import React from "react";
import { useSelector, useDispatch } from "react-redux"; // import 해주세요.

useDispatch는 react-redux에서 임포트 해와야 사용할 수 있는 hook(기능)이라서 useSelector 옆에 넣었다.

// src/App.js

import React from "react";
import { useSelector, useDispatch } from "react-redux"; // import 해주세요.

const App = () => {
	const dispatch = useDispatch();
	
  return 
  	<div>
        <button>
        +1
        </button>
    </div>;
}

export default App;

그리고 App 컴포넌트 제일 윗 줄에 dispatch를 추가해줬다.

여기있는 dispatch는 함수이기때문에 괄호를 꼭 붙여서 함수를 실행해야한다.

그리고 괄호안에는 액션객체를 넣어주면 된다.

 

// src/App.js

import React from "react";
import { useSelector, useDispatch } from "react-redux"; // import 해주세요.

const App = () => {
	const dispatch = useDispatch();
	
  return 
  	<div>
        <button onClick = {() =>{
        	dispatch({type:"PLUS_ONE"})
        }}>
        +1
        </button>
    </div>;
}

export default App;

button에 액션을 주기 위해 onClick 이벤트를 써주고 dispatch에 "PLUS_ONE"이라는 키값을 정해줬다.
이렇게 하면 버튼을 눌렀을때 dispatch를 통해서 "PLUS_ONE"이라는 액션을 취하라고 하는 것이다.

여기까지 하면 우리는 이제 액션객체를 리듀서로 보낼 수 있게 됐다.
이제는 그 액션객체를 받아서 무엇을 해야하는지 코드를 작성해줄 차례이다.

액션 객체를 받는 방법 ( 모듈로 넘어가서 받는다.)

// src/modules/counter.js

// 초기 상태값
const initialState = {
  number: 0,
};

// 리듀서
const counter = (state = initialState, action) => {
  console.log(action)
  switch (action.type) {
    default:
      return state;
  }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default counter;

 객체를 받는 코드를 작성하기 전 액션이 잘 넘어오는지 확인부터 해야한다.

카운터 리듀서 제일 첫번째 줄에 콘솔로그를 찍어봤다.

이런 식으로 버튼을 누를때 마다 키값이 잘 나오는 것을 볼 수 있다.

확인이 됐으면 이제 state에있는 number를 실제로 변경하는 로직을 만들면 된다.

// src/modules/counter.js

// 초기 상태값
const initialState = {
  number: 0,
};

// 리듀서
const counter = (state = initialState, action) => {
  console.log(action)
  switch (action.type) {
    case "PLUS_ONE":
      return {number: state.number + 1};
    default:
      return state;
  }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default counter;

switch문을 활용해서 액션을 취했을 때 number가 바뀌도록 코드를 넣었다.

이제 실행이 잘 되는지 App.js에서 number를 확인하는 코드를 추가해본다.

// src/App.js

import React from "react";
import { useSelector, useDispatch } from "react-redux"; // import 해주세요.

const App = () => {
	const dispatch = useDispatch();
    const number = useSelector((state) => state.counter.number);
    console.log(number);
	
  return 
  	<div>
    	{number}
        <button onClick = {() =>{
        	dispatch({type:"PLUS_ONE"})
        }}>
        +1
        </button>
    </div>;
}

export default App;

 useSelector를 활용해서 number가 맞게 나오는지 확인한다. 여기에 콘솔로그까지 찍어야 실행했을 때 콘솔창에서 확인 할 수 있다.
그리고 <div> 에도 넘버가 잘 나오는지 확인 해보고자 {number}를 넣어줬다.

+1 버튼을 누를 때 마다 콘솔창에도, 웹에도 숫자가 하나씩 올라가는 것을 볼 수 있다.

 

* 지금까지 내용정리 💡

액션객체는 반드시 type 이라는 key가 있어야 하고, 리듀서로 보낼 명령이다. (액션 = 명령)
dispatch란 액션객체를 리듀서로 보내는 전달자 함수이다.

reducer란 dispatch를 통해 전달 받은 액션객체를 검사하고,
조건이 일치할 경우 새로운상태값을 만들어내는 함수이다. (switch)

dispatch를 사용하기 위해서는 usedispatch라는 hook을 이용해야한다. (import해줘야 한다)
dispatch는 store에 내장함수로 액션을 발생시킨다. (일단 이 정도로만 이해하고 넘어가면된다)

액션객체의 type의 value는 대문자로 작성해야한다. ( JS에서 상수는 대문자로 쓰라는 룰이 있다고 한다.)

 


action creator에 대한 정리

action creator를 사용하는 이유

액션객체를 한곳에서 관리 할 수 있도록 함수와 액션value 상수를 이용하게 된다.

export const plusOne = () => {
  return {
    type: PLUS_ONE,
  };
};

위 코드가 action creator : 액션을 만드는 생성자 이다.

플러스원이라는 함수가 액션객체를 반환해 주고있다.

const PLUS_ONE = "PLUS_ONE";

위 코드가 상수로 값을 주는 action value 이다.

// src/modules/counter.js

// 추가된 코드 👇 - 액션 value를 상수들로 만들어 줍니다. 보통 이렇게 한곳에 모여있습니다.
const PLUS_ONE = "PLUS_ONE";
const MINUS_ONE = "MINUS_ONE";


// 추가된 코드 👇 - Action Creator를 만들어 줍니다. 
export const plusOne = () => {
  return {
    type: PLUS_ONE,
  };
};

export const minusOne = () => {
  return {
    type: MINUS_ONE,
  };
};

그 action value 상수를 이용해서 type을 반환하는 함수인 action creator가 추가 되었다.

// src/modules/counter.js

// 추가된 코드 👇 - 액션 value를 상수들로 만들어 줍니다. 보통 이렇게 한곳에 모여있습니다.
const PLUS_ONE = "PLUS_ONE";
const MINUS_ONE = "MINUS_ONE";


// 추가된 코드 👇 - Action Creator를 만들어 줍니다. 
export const plusOne = () => {
  return {
    type: PLUS_ONE,
  };
};

export const minusOne = () => {
  return {
    type: MINUS_ONE,
  };
};


// 초기 상태값
const initialState = {
  number: 0,
};

// 리듀서
const counter = (state = initialState, action) => {
  switch (action.type) {
    case PLUS_ONE: // case에서도 문자열이 아닌, 위에서 선언한 상수를 넣어줍니다. 
      return {
        number: state.number + 1,
      };
    case MINUS_ONE: // case에서도 문자열이 아닌, 위에서 선언한 상수를 넣어줍니다. 
      return {
        number: state.number - 1,
      };
    default:
      return state;
  }
};


export default counter;

위 코드가 counter.js 의 전체 코드이다.

 

이제 이 action creator는 component에서 어떻게 사용되는지 알아볼 차례이다.

// src/App.js

import React from "react";
import { useSelector, useDispatch } from "react-redux"; // import 해주세요.

const App = () => {
	const dispatch = useDispatch();
    const number = useSelector((state) => state.counter.number);
    console.log(number);
	
  return 
  	<div>
    	{number}
        <button onClick = {() =>{
        	dispatch({type:"PLUS_ONE"})
        }}>
        +1
        </button>
        <button onClick = {() =>{
        	dispatch({type:"MINUS_ONE"})
        }}>
        -1
        </button>
    </div>;
}

export default App;

( 참고로 위에 있던 마지막 App.js 코드와 다른점은 마이너스 버튼을 만들어줬다는 점이다.)

action creator가 외부에서 사용되려면 export되야하는데,
counter.js 코드를 살펴보면 export const plusOne / minusOne 으로 되어있는 것을 볼 수 있다
이렇게 export해줬다면 App.js에 improt 해주는 일만 남았다.

// src/App.js

import React from "react";
import { useSelector, useDispatch } from "react-redux"; 
import { plusOne, minusOne } from "./redux/modules/counter";   // import 해주세요.

const App = () => {
	const dispatch = useDispatch();
    const number = useSelector((state) => state.counter.number);
    console.log(number);
	
  return 
  	<div>
    	{number}
        <button onClick = {() =>{
        	dispatch({type:"PLUS_ONE"})
        }}>
        +1
        </button>
        <button onClick = {() =>{
        	dispatch({type:"MINUS_ONE"})
        }}>
        -1
        </button>
    </div>;
}

export default App;

코드 위쪽으로 import된 plusOne과 minusOne을 볼 수 있다.
이제 하트코딩했던 dispatch에 action creator를 넣어주면 된다.

// src/App.js

import React from "react";
import { useSelector, useDispatch } from "react-redux"; 
import { plusOne, minusOne } from "./redux/modules/counter";   // import 해주세요.

const App = () => {
	const dispatch = useDispatch();
    const number = useSelector((state) => state.counter.number);
    console.log(number);
	
  return 
  	<div>
    	{number}
        <button onClick = {() =>{
        	dispatch(plusOne());
        }}>
        +1
        </button>
        <button onClick = {() =>{
        	dispatch(minusOne());
        }}>
        -1
        </button>
    </div>;
}

export default App;

하드코딩 된 부분에 action creator인 plusOne()과 minusOne()이 들어간 것을 확인 할 수 있다.

 

action creator를 사용하는 이유 💡

1. 휴먼에러를 방지 할 수 있다.
   액션객체 type value를 상수로 만들어놨기 때문에 개발툴에서 자동완성기능이 지원받을 수 있다.

2. 유지보수 효율성이 증가한다.
   규모가 큰 프로젝트에서 action creator를 수정해야하는 경우, 하나하나 바꿔야되는데
   action creator속 type부분을 변경해주면모든 수정사항을 변경할 수 있다.

3. 코드 가독서이 높아진다.

 

 

✅ 리덕스 공식문서에서 action creator에 대해 자세히 나와있으니 한번 살펴보자!


 

payload

카운터 프로그램을 사용하는 사용자가 직접 몇을 더하고 몇을 뺄지를 정할 수 있도록 하고싶다면 payload를 쓴다.

import React form "react";
import { useState } from "react";

const App = () => {
  const [number, setNumber] = useState(0);
  const onChangeHandler = (event) => {
   	const {value} = event.target;
        setNumber(+value)
  }
     console.log(number);

	return(
        <div>
            <input type="number" onChange={onChangeHandler}/>
            <button>더하기</button>
            <button>빼기</button>
        </div>

}

우선 위 코드에서 setNumber(+value)에서 +는 숫자를 더한다는 개념이 아니라 이벤트핸들러를 썼을때 자동으로 문자열로 설정이 되어있어서 숫자형으로 형변환 하기 위해 +를 붙였습니다.

아래에 콘솔로그를 찍어서 확인해본다.

이제 counter.js로 가서 action creator를 만들어본다.

 

// src/redux/modules/counter.js

// action value
const ADD_NUMBER = "ADD_NUMBER";

// action creator
export const addNumber = (payload) =>{
	return {
    	type:ADD_NUMBER,
        payload:payload
    }
}
// initial state
const initialState={
	number: 0,
};
// reducer
const counter = (state=initialState, action) =>{
	switch (action.type){
    	case ADD_NUMBER:{
        	return {
            	number: state.number + action.payload
            };
        }
    	default:
    		return state;
    }
    
}

// export default reducer
export default counter;

모듈에 내가 뭘 만들어야할지 빈 파일에 주석처리한 내용을 심고
하나하나 코드를 작성해 보자.

payload가 필요한 action creator는 지금까지 작성한 action creator와  차이가 있다.

함수를 선언할때 매개변수 자리에 payload를 넣어줘야한다.

그 이유는 action creator를 사용하는 컴포넌트에서 reducer를 보내고자하는 payload를 인자를 넣을 예정이기 때문이다.

위 action creator를 보면 payload:payload로 키:밸류가 들어있는걸 볼 수 있는데, 키와 밸류가 같으면 하나만 적어도 된다.

// action creator
export const addNumber = (payload) =>{
	return {
    	type:ADD_NUMBER,
        payload
    }
}

 

 

 

이제 App.js로 가서

store에 있는 값을 가져와야한다. useSelector를 사용 

import React form "react";
import { useState } from "react";
import { useSelector } from "react-redux";

const App = () => {
  const [number, setNumber] = useState(0);
  const globalNumber =useSelector((state) => state.counter.number)
  const onChangeHandler = (event) => {
   	const {value} = event.target;
        setNumber(+value)
  }
     console.log(number);

	return(
        <div>
            <input type="number" onChange={onChangeHandler}/>
            <button>더하기</button>
            <button>빼기</button>
        </div>

}

먼저 useSelector를 import한다.

useSelector로 가져온 값을 변수로 선언한다. (globalNumber) 

여기까지 했다면 이제 action creator를 import하고 payload에 담아서 dispatch하면 된다.

import React form "react";
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { addNumber } from "./redux/modules/counter";

const App = () => {
  const [number, setNumber] = useState(0);
  const globalNumber =useSelector((state) => state.counter.number)
  const dispatch = useDispatch();
  const onChangeHandler = (event) => {
   	const {value} = event.target;
        setNumber(+value)
  };
  const onClickAddNumberHandler = () => {}
     console.log(number);

	return(
        <div>
            <input type="number" onChange={onChangeHandler}/>
            <button onClick={onClickAddNumberHandler}>더하기</button>
            <button>빼기</button>
        </div>

}

우선 더하기 버튼을 만들었다.

onClickAddNumberHandler로 이벤트핸들러를 만들고
버튼에 onClick을 만들었다.

그 후 action creator를 import했다.

 

이제 더하기 버튼을 눌렀을때 무엇을 하게 해야하나를 생각해본다.
여기서는 action creator를 dispatch해주고 action creator인자에 number를 넣어주면 된다.

import React form "react";
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { addNumber } from "./redux/modules/counter";

const App = () => {
  const [number, setNumber] = useState(0);
  const globalNumber =useSelector((state) => state.counter.number)
  const dispatch = useDispatch();
  const onChangeHandler = (event) => {
   	const {value} = event.target;
        setNumber(+value)
  };
  const onClickAddNumberHandler = () => {
  	dispatch(addNumber(number)) ;
  }
     console.log(number);

	return(
        <div>
        	{globalNumber}
            <input type="number" onChange={onChangeHandler}/>
            <button onClick={onClickAddNumberHandler}>더하기</button>
            <button>빼기</button>
        </div>

}

위 코드는 다 완성 됐다.

이제 테스트르 해볼 차례이다.

 

 

인풋창에 숫자를 입력하고, 더하기 or 빼기 버튼을 누르면 인풋창 왼쪽에 숫자가 바뀌는 것을 볼 수 있다.

 


Ducks pattern ( Erik Rasmussen ) - 리덕스 모듈 작성방법의 정석

  1.  Reducer 함수를 export defualt 한다.
  2.  action creator 함수들을 export 한다.
  3.  action의 type은 app reducer action-type의 형태로 작성한다.
    모듈 파일 1개에 action-type, action creator, reducer 모두 존재하는 작성방식이다.

 

* 지금까지 내용정리 💡

reducer로 보내는 액션객체에 어떤 정보를 같이 담아 보내고자 한다면 payload를 이용한다.
payload는 action creator를 생성할때 매개변수 자리에서 받을 준비를 하고 반환하는 액션객체에
payload안 key와 받은 매개변수를 value 로 하여 구현한다.
reducer에서 payload를 사용하고자 할 때는 action.payload 로 사용할 수 있다.

 


 

위에서 미쳐 적용하지 못한 빼기버튼에 대한 코드를 작성해 봤다.

 

▼ app.js

import React form "react";
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { addNumber, minusNumber } from "./redux/modules/counter";

const App = () => {
  const [number, setNumber] = useState(0);
  const globalNumber =useSelector((state) => state.counter.number)
  const dispatch = useDispatch();
  const onChangeHandler = (event) => {
   	const {value} = event.target;
        setNumber(+value)
  };
  const onClickAddNumberHandler = () => {
  	dispatch(addNumber(number));
  };
  const onClickMinusNumberHandler = () => {
  	dispatch(minusNumber(number));
  };
     console.log(number);

	return(
        <div>
        	{globalNumber}
            <input type="number" onChange={onChangeHandler}/>
            <button onClick={onClickAddNumberHandler}>더하기</button>
            <button onClick={onClickMinusNumberHandler}>빼기</button>
        </div>

}

 

▼ counter.js

// src/redux/modules/counter.js

// action value
const ADD_NUMBER = "ADD_NUMBER";
const MINUS_NUMBER = "MINUS_NUMBER";

// action creator
export const addNumber = (payload) =>{
	return {
    	type:ADD_NUMBER,
        payload
    }
}
export const minusNumber = (payload) =>{
	return {
    	type:MINUS_NUMBER,
        payload
    }
}
// initial state
const initialState={
	number: 0,
};
// reducer
const counter = (state=initialState, action) =>{
	switch (action.type){
    	case ADD_NUMBER:{
        	return {
            	number: state.number + action.payload
            };
        }
        case MINUS_NUMBER:{
        	return {
            	number: state.number - action.payload
            };
        }
    	default:
    		return state;
    }
    
}

// export default reducer
export default counter;
728x90
LIST