24.05.29 Redux 4,5,6
[ Redux 4 - Redux 기반 TodoList 만들기 ]
∙ 폴더구조
∙ 코드도 강의 따라서 그대로
// App.jsx
import AddForm from "./components/AddForm";
import TodoList from "./components/TodoList";
const App = () => {
return (
<div>
<h1>Todo</h1>
<AddForm />
<TodoList />
</div>
);
};
export default App;
// AddForm.jsx
import { useState } from "react";
import { useDispatch } from "react-redux";
import { addTodo } from "../redux/modules/todos";
const AddForm = () => {
const [todo, setTodo] = useState("");
const dispatch = useDispatch();
return (
<div>
<input
type="text"
value={todo}
onChange={(e) => {
setTodo(e.target.value);
}}
/>
<button
onClick={() => {
dispatch(
addTodo({
id: new Date().getTime(),
title: todo,
})
);
}}
>
추가
</button>
</div>
);
};
export default AddForm;
// TodoList.jsx
import { useSelector } from "react-redux";
const TodoList = () => {
const todos = useSelector((state) => state.todos);
console.log(todos);
return (
<div>
{todos.map(function (todo) {
return <div key={todo.id}>{todo.title} </div>;
})}
</div>
);
};
export default TodoList;
// configStore.js
import { combineReducers } from "redux";
import todos from "../modules/todos";
import { createStore } from "redux";
const rootReducer = combineReducers({
todos: todos,
});
const store = createStore(rootReducer);
export default store;
// main.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import "./index.css";
import { Provider } from "react-redux";
import store from "./redux/config/configStore.js";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
// todos.js
// action value
const ADD_TODO = "ADD_TODO";
// action creator 만들어서 export(컴포넌트에서 사용할 수 있도록)
export const addTodo = (payload) => {
return {
type: ADD_TODO,
payload: payload,
};
};
// state init
const initialState = [
{
id: 1,
title: "react를 배워봅시다.",
},
{
id: 2,
title: "redux를 배워봅시다.",
},
];
const todos = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
return [...state, action.payload];
default:
return state;
}
};
export default todos;
[ Redux 5 - RTK(Redux ToolKit)]
(Redux ToolKit)이 뭘까?
redux의 코드는 더 간략히, 더 편하게 쓰기 위한 기능들을 흡수해 만든 것 👉🏻 리덕스를 개량한 것
$ yarn add react-redux @reduxjs/toolkit 으로 설치
✔️ 이젠 modules안쓰고 slices로 사용한다.
▼ 툴킷 사용한 수정코드
[ Redux Devtools ]
현재 프로젝트의 state 상태라던가, 어떤 액션이 일어났을 때 그 액션이 무엇이고, 그것으로 인해 state가 어떻게 변경되었는지 등 리덕스를 사용하여 개발할 때 아주 편리하게 사용할 수 있다.
[ Flux 패턴 ]
Facebook에 의해 개발된 애플리케이션 아키텍처로, 주로 React와 함께 사용되며 데이터의 단방향 흐름을 강조한다.
Flux 아키텍처는 다음 네 가지 주요 구성 요소로 이루어져 있다.
1. Dispatcher: 애플리케이션 내 모든 데이터 흐름을 관리하는 중앙 허브 역할을 한다. 액션들이 발생하면 디스패처를 통해 스토어로 전달
2. Stores: 애플리케이션의 상태(데이터)와 로직을 보유한다. 스토어는 디스패처를 통해 전달된 액션에 반응하여 상태를 변경하고, 변경 사항을 뷰에 알림
3. Actions: 상태 변화를 일으킬 때 사용하는 간단한 객체이며 사용자 인터페이스에서 발생한 사용자의 행동을 액션으로 표현하고, 이를 디스패처를 통해 스토어로 전달한다.
4. Views (React Components): 사용자 인터페이스를 구성하는 React 컴포넌트들로 스토어에서 상태가 변하면, 뷰는 이를 반영하여 사용자 인터페이스를 업데이트한다.
Ducks - Redux 코드의 구조를 단순화하는 데 초점
Flux - 애플리케이션의 데이터 흐름을 체계화하는 데 중점
( Ducks 패턴과 Flux 패턴은 서로 다른 측면에 초점을 맞추고 있지만, 그 근본적인 목적은 모두 애플리케이션의 상태 관리와 데이터 흐름의 체계를 잡는 것이다. 특히 Redux를 사용하는 React 애플리케이션에서 이 둘은 함께 사용될 수 있다. )
https://bestalign.github.io/translation/cartoon-guide-to-flux/
Flux로의 카툰 안내서
원문: https://medium.com/code-cartoons/a-cartoon-guide-to-flux-6157355ab207 Flux…
bestalign.github.io
https://taegon.kim/archives/5288
Flux와 Redux
이 글에서는 Facebook에서 React와 함께 소개한 Flux 아키텍처에 대해 알아보고 Flux를 구현한 Redux 라이브러리를 살펴본 후 이를 적용한 간단한 React 애플리케이션을 작성해보겠다. 본문에 사용된 코
taegon.kim
[ Redux 6 - [실습] RTK 기반 TodoList 고도화 ]
폴더 재구성 (slices)
▼ todos.js → todosSlice.js로 RTK사용 재구성
// todosSlice.js
import { createSlice } from "@reduxjs/toolkit";
// state init
const initialState = [
{
id: 1,
title: "react를 배워봅시다.",
},
{
id: 2,
title: "redux를 배워봅시다.",
},
];
const todosSlice = createSlice({
name: "todos",
initialState,
reducers: {
addTodo: (state, action) => {
return [...state, action.payload];
},
},
});
export const { addTodo } = todosSlice.actions;
export default todosSlice.reducer;
▼ configStore.js RTK사용 수정
// configStore.js
import { configureStore } from "@reduxjs/toolkit";
import todosSlice from "../slices/todosSlice";
const store = configureStore({
reducer: {
todos: todosSlice,
},
});
export default store;
▼ AddForm.jsx import 수정
// AddForm.jsx
import { addTodo } from "../redux/slices/todosSlice";
// import { addTodo } from "../redux/modules/todos";
자바스크립트 베이직 과제 - todoList
import { useState } from "react";
import { v4 as uuidv4 } from "uuid";
function App() {
const [input, setInput] = useState("");
const [todos, setTodos] = useState([
{
id: 1,
text: "베이직과제",
completed: true,
},
{
id: 2,
text: "제출하기",
completed: false,
},
]);
const handleInput = (e) => {
setInput(e.target.value);
};
const handleAddTodo = (e) => {
e.preventDefault();
if (!input.trim()) return;
const newTodo = {
id: uuidv4(),
text: input,
completed: false,
};
setTodos([...todos, newTodo]);
setInput("");
};
const handleDelete = (id) => {
setTodos(todos.filter((todo) => todo.id !== id));
};
const handleToggle = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
);
};
return (
<div>
<h1>할 일 목록</h1>
<form onSubmit={handleAddTodo}>
<input
type="text"
placeholder="할 일을 추가하세요"
value={input}
onChange={handleInput}
/>
<button type="submit">추가</button>
</form>
<ul>
{todos.map((todo) => (
<li
key={todo.id}
style={{ textDecoration: todo.completed ? "line-through" : "none" }}
>
{todo.text}
<button
onClick={() => {
handleToggle(todo.id);
}}
>
{todo.completed ? "취소" : "완료"}
</button>
<button
onClick={() => {
handleDelete(todo.id);
}}
>
삭제
</button>
</li>
))}
</ul>
</div>
);
}
export default App;