리덕스를 쓰는 방법은 다양하다. 그래서 더더욱 나에게 좋은 파일 형태를 찾아 먼저 익숙해 지는 것이 리덕스를 이해하는데 도움이 될 것이라 생각했다.
따라서 간단해 보이는 리덕스 파일구조를 정리하고, 이를 우선적으로 몸에 익히려 한다.
import { createStore } from "redux";
import { combineReducers } from "redux";
import counter from "../modules/counter";
const rootReducer = combineReducers({
counter: counter,
});
const store = createStore(rootReducer);
export default store;
// 원래부터 있던 코드
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
// 우리가 추가할 코드
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>
);
Action Value : 액션 타입 정의하기
모듈 이름/ 액션 이름
으로 작성하면 좋다. const ADD_NUMBER = "counter/ADD_NUMBER";
const MiNUS_NUMBER = "counter/MINUS_NUMBER";
Action Creator : 액션 생성 함수 만들기
// Action Creator
export const addNumber = (payload) => {
return {
type: ADD_NUMBER,
//키와 value가 같으면 하나로 줄여 작성 가능 ES6
payload,
};
};
export const minusNumber = (payload) => {
return {
type: MiNUS_NUMBER,
payload,
};
};
// Initial State
const initialSate = {
number: 0,
};
// state 값이 하나인 경우
// Initial State
const initialSate = {
number: 0,
};
// Reducer
const counter = (state = initialSate, 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;
}
};
// state 값이 여럿인 경우
// Initial State
const initialSate = {
input: '',
todos: [{id: 1, text: '리덕스 기초 배우기', done: true},
{id: 2, text: '리덕스와 리덕스 사용하기', done: false}]
};
// Reducer
const counter = (state = initialSate, action) => {
switch (action.type) {
case CHANGE_INPUT: {
return {
...state,
input: action.input
};
}
case INSERT: {
return {
...state,
todos: state.todos.concat(action.todo)
};
}
case TOGGLE: {
return {
...state,
todos: state.todos.map(todo =>
todo.id === todo.id?{...todo, done:!todo.done}:todo
};
}
default:
return state;
}
};
import { useSelector} from "react-redux";
const globalNumber = useSelector((state) => state.counter.number);
<div>{globalNumber}<div>
import { useDispatch} from "react-redux";
import { addNumber, minusNumber } from "./redux/modules/counter";
const dispatch = useDispatch();
const onClickAddNumberHandler = () => {
dispatch(addNumber(number));
};
const onClickMinusNumberHandler = () => {
dispatch(minusNumber(number));
};
return (
<div>
{globalNumber}
<input type="number" onChange={onChangeHandler} value={number} />
<button onClick={onClickAddNumberHandler}>더하기</button>
<button onClick={onClickMinusNumberHandler}>빼기</button>
</div>
);
// src/App.js
import React, { 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 = (e) => {
const { value } = e.target;
setNumber(+value);
};
const onClickAddNumberHandler = () => {
dispatch(addNumber(number));
};
const onClickMinusNumberHandler = () => {
dispatch(minusNumber(number));
};
return (
<div>
{globalNumber}
<input type="number" onChange={onChangeHandler} value={number} />
<button onClick={onClickAddNumberHandler}>더하기</button>
<button onClick={onClickMinusNumberHandler}>빼기</button>
</div>
);
};
export default App;