createStore
- 스토어를 만드는 함수
- store.getState() : 현재 store의 state를 가져오는 함수
- store.dispatch(액션) : 액션을 인자로 넣어 store의 상태를 변경시키는 함수
- store.dispatch(액션생성자()) : store의 상태를 변경시키는 함수
- store.unsubscribe = store.subscribe(() => {}) : store에 변경이 생겼을 때, () => {} 함수를 실행
- 리턴이 unsubscribe
- unsubscribe() 하면 구독된 함수 제거
- store.replaceReducer(다른 리듀서) : 원래 가지고 있던 리듀서를 다른 리듀서로 바꿈
const store = createStore(리듀서);
createStore<S> (
reducer: Reducer<S>,
preloadedState: S,
enhancer?: StoreEnhancer<S>
): Store<S>;
// src/redux/store.js
import { createStore } from "redux";
import { todoApp } from "./reducers";
const store = createStore(todoApp);
export default store;
// index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import store from "./redux/store";
import { addTodo } from "./redux/actions";
const unsubscribe = store.subscribe(() => {
console.log(store.getState());
});
store.dispatch(addTodo("coding"));
store.dispatch(addTodo("read book"));
store.dispatch(addTodo("eat"));
unsubscribe();
store.dispatch(addTodo("coding"));
store.dispatch(addTodo("read book"));
store.dispatch(addTodo("eat"));
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
reportWebVitals();
- 스토어 만들기
// src/redux/store.js
import { todoApp } from "./reducers";
import { createStore } from "redux";
import { addTodo } from "./actions";
const store = createStore(todoApp);
console.log(store);
console.log(store.getState());
setTimeout(() => {
store.dispatch(addTodo("hello"));
}, 1000);
export default store;
// index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import store from "./redux/store";
store.subscribe(() => {
const state = store.getState();
console.log("store changed", state);
});
ReactDOM.render(<App />, document.getElementById("root"));
serviceWorker.unregister();
- 로직 추가하기
- action 정의
- action 생성자 만들기
- reducer 수정
// src/redux/actions.js
// action 정의
// 액션의 type 정의
// 액션의 타입 -> 액션 생성자 이름
// ADD_TODO -> addTodo
export const ADD_TODO = "ADD_TODO";
export const COMPLETE_TODO = 'COMPLETE_TODO';
// 액션 생산자
// 액션의 타입은 미리 정의한 타입으로부터 가져와서 사용
// 사용자가 인자로 주지 않음
export function addTodo(text) {
return { type: ADD_TODO, text}; // { type: ADD_TODO, text: text}
// src/redux/actions.js
// action 생성자 만들기
export const ADD_TODO = "ADD_TODO";
export const COMPLETE_TODO = 'COMPLETE_TODO';
export function addTodo(text) {
return { type: ADD_TODO, text};
export function completeTodo(index) {
return { type: COMPLETE_TODO, index }; // { type: COMPLETE_TODO, index: index }
}
// src/redux/reducer.js
// reducer 수정
import { ADD_TODO, COMPLETE_TODO } from "./actions";
export function todoApp(previousState, action) {
if (previousState === undefined) {
return [];
}
if (action.type === ADD_TODO) {
return [...previousState, { text: action.text, completed: false }];
}
if (action.type === COMPLETE_TODO) {
const newState = [];
for (let i = 0; i < previousState.length; i++) {
newState.push(
i === action.index
? { ...previousState[i], completed: true }
: { ...previousState[i] }
);
}
return newState;
}
return previousState;
}
// src/redux/store.js
// dispatch
import { todoApp } from "./reducers";
import { createStore } from "redux";
import { addTodo, completeTodo } from "./actions";
const store = createStore(todoApp);
console.log(store);
console.log(store.getState());
setTimeout(() => {
store.dispatch(addTodo("hello"));
setTimeout(() => {
store.dispatch(completeTodo(0));
}, 1000);
}, 1000);
export default store;
- 애플리케이션이 커지면, state가 복잡해 짐
- 리듀서를 크게 만들고, state를 변경하는 모든 로직을 담을 수 있음
- 리듀서를 분할해서 만들고, 합치는 방법을 사용할 수 있음
- todos만 변경하는 액션들을 처리하는 A 리듀서 함수를 만들고,
- filter만 변경하는 액션들을 처리하는 B 리듀서 함수를 만들고,
- A와 B를 합침
[
{
text: "Hello",
completed: false
}
]
// ------------------------------
{
todos: [
{
text: "Hello",
completed: false
}
],
filter: "SHOW_ALL"
}
- 한번에 다하는 리듀서
// src/redux/reducer.js
import { ADD_TODO, COMPLETE_TODO } from "./actions";
export function todoApp(previousState, action) {
if (previousState === undefined) {
return { todos: [], filter: "SHOW_ALL" };
}
if (action.type === ADD_TODO) {
return {
todos: [...previousState.todos, { text: action.text, completed: false }],
filter: previousState.filter,
};
}
if (action.type === COMPLETE_TODO) {
const newState = [];
for (let i = 0; i < previousState.todos.length; i++) {
newState.push(
i === action.index
? { ...previousState.todos[i], completed: true }
: { ...previousState.todos[i] }
);
}
return { todos, filter: previousState.filter };
}
return previousState;
}
- 리듀서 분리
// src/redux/reducer.js
export function todos(previousState, action) {
if (previousState === undefined) {
return [];
}
if (action.type === ADD_TODO) {
return [...previousState, { text: action.text, completed: false }];
}
if (action.type === COMPLETE_TODO) {
const newState = [];
for (let i = 0; i < previousState.length; i++) {
newState.push(
i === action.index
? { ...previousState[i], completed: true }
: { ...previousState[i] }
);
}
return newState;
}
return previousState;
}
export function filter(previousState, action) {
if (previousState === undefined) {
return "SHOW_ALL";
}
return previousState;
}
- 리듀서 합치기
export function todoApp(previousState = {}, action) {
return {
todos: todos(previousState.todos, action),
filter: filter(previousState.filter, acition),
};
}
댓글남기기