π¦₯
41μΌμ°¨
Part 11. Redux λ‘ μνκ΄λ¦¬νκΈ°
Ch 1. Redux Basic
Ch 1. Redux Basic
$ npm i redux
- λ¨μΌ μ€ν μ΄λ€!
- [λ§λ€κΈ°] λ¨μΌ μ€ν μ΄ μ¬μ© μ€λΉνκΈ°
- import redux
- μ‘μ μ μ μνκ³ ,
- μ‘μ μ μ¬μ©νλ, 리λμλ₯Ό λ§λ€κ³ ,
- 리λμλ€μ ν©μΉλ€.
- μ΅μ’ ν©μ³μ§ 리λμλ₯Ό μΈμλ‘, λ¨μΌ μ€ν μ΄λ₯Ό λ§λ λ€
- [μ¬μ©νκΈ°] μ€λΉν μ€ν μ΄λ₯Ό 리μ‘νΈ μ»΄ν¬λνΈμμ μ¬μ©νκΈ°
- import react-redux
- connect ν¨μλ₯Ό μ΄μ©ν΄μ μ»΄ν¬λνΈμ μ°κ²°
π Action (μ‘μ )
function μ‘μ
μμ±μ(...args) { return μ‘μ
; }
- μ‘μ μμ±μλ₯Ό ν΅ν΄ μ‘μ μ λ§λ€μ΄ λ λλ€.
- λ§λ€μ΄λΈ μ‘μ κ°μ²΄λ₯Ό 리λμ€ μ€ν μ΄μ 보λ λλ€.
- 리λμ€ μ€ν μ΄κ° μ‘μ κ°μ²΄λ₯Ό λ°μΌλ©΄ μ€ν μ΄μ μν κ°μ΄ λ³κ²½ λ©λλ€.
- λ³κ²½λ μν κ°μ μν΄ μνλ₯Ό μ΄μ©νκ³ μλ μ»΄ν¬λνΈκ° λ³κ²½λ©λλ€.
- μ‘μ μ μ€ν μ΄μ 보λ΄λ μΌμ’ μ μΈνμ΄λΌ μκ°ν μ μμ΅λλ€.
// ./redux/actions.js
export const ADD_TODO = "ADD_TODO";
export function addTodo(todo) {
return { type: ADD_TODO, todo };
}
π Reducer (리λμ) : Immutable(λΆλ³)
function 리λμ(previousState, action) {
return newState;
}
// ./redux/reducers.js
import { ADD_TODO } from "./actions";
// state
// ['μ½λ©', 'μ μ¬ λ¨ΉκΈ°']
const initialState = [];
export function todoApp(previousState = initialState, action) {
// μ΄κΈ°κ°μ μ€μ ν΄μ£Όλ λΆλΆ
// if (previousState === undefined) {
// return [];
// }
if (action.type === ADD_TODO) {
return [...previousState, action.todo];
}
return previousState;
}
π createStore : μ€ν μ΄λ₯Ό λ§λλ ν¨μ
const store = createStore(리λμ);
createStore<S>(
reducer: Reducer<S>,
preloadedState: S,
enhancer?: StoreEnhancer<S>
): Store<S>;
- store.getState();
- νμ¬ state μ store λ₯Ό κ°μ Έμ¨λ€.
- store.dispatch(μ‘μ
);, store.dispatch(μ‘μ
μμ±μ());
- action μ μΈμλ‘ λ£μ΄μ, state μ μνλ₯Ό λ³κ²½μν¨λ€.
- const unsubscribe = store.subscribe(() => {});
- 리ν΄μ΄ unsubscribe λΌλ μ !
- unsubscribe(); νλ©΄ μ κ±°
- store μ λ³κ²½μ΄ μκ²Όμ λ ν¨μλ₯Ό μ€ννλ€.
- store.replaceReducer(λ€λ₯Έλ¦¬λμ);
- μλ κ°μ§κ³ μλ 리λμλ₯Ό λ€λ₯Έ 리λμλ‘ λ°κΎΌλ€.
- μ μ μ°μ.
// ./redux/store.js
import { createStore } from "redux";
import { todoApp } from "./reducer";
const store = createStore(todoApp);
export default store;
// ./index.js
...
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"));
...
π combineReducers
// ./redux/action.js
export const ADD_TODO = "ADD_TODO";
export const COMPLETE_TODO = "COMPLETE_TODO";
// {type: ADD_TODO, text: 'ν μΌ'}
export function addTodo(text) {
return {
type: ADD_TODO,
text,
};
}
// {type: COMPLETE_TODO, index: 3}
export function completoTodo(index) {
return {
type: COMPLETE_TODO,
index,
};
}
export const SHOW_ALL = "SHOW_ALL";
export const SHOW_COMPLETE = "SHOW_COMPLETE";
export function showAll() {
return { type: SHOW_ALL };
}
export function showComplete() {
return { type: SHOW_COMPLETE };
}
// ./redux/reducers/todos.js
import { ADD_TODO, COMPLETE_TODO } from "../actions";
const initialState = [];
// [{text: 'μ½λ©', done: false}, {text: 'μ μ¬ λ¨ΉκΈ°', done: false}]
export default function todos(previousState = initialState, action) {
if (action.type === ADD_TODO) {
return [...previousState, { text: action.text, done: false }];
}
if (action.type === COMPLETE_TODO) {
return previousState.map((todo, index) => {
if (index === action.index) {
return { ...todo, done: true };
}
return todo;
});
}
return previousState;
}
// ./redux/reducers/filter.js
import { SHOW_ALL, SHOW_COMPLETE } from "../actions";
const initialState = "ALL";
// 'ALL'
export default function filter(previousState = initialState, action) {
if (action.type === SHOW_COMPLETE) {
return "COMPLETE";
}
if (action.type === SHOW_ALL) {
return "ALL";
}
return previousState;
}
// ./redux/reducers/reducer.js
import { combineReducers } from "redux";
import todos from "./todos";
import filter from "./filter";
const reducer = combineReducers({
todos,
filter,
});
export default reducer;
// ./redux/store.js
import { createStore } from "redux";
import reducer from "./reducers/reducer";
const store = createStore(reducer);
export default store;
// ./index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import store from "./redux/store";
import { addTodo, completoTodo, showComplete } from "./redux/actions";
store.subscribe(() => {
console.log(store.getState());
});
store.dispatch(addTodo("ν μΌ"));
store.dispatch(completoTodo(0));
store.dispatch(showComplete(0));
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
π Redux λ₯Ό React μ μ°κ²°
- react-redux μ μ°κ³ μ°κ²°νκΈ° (Context API)
// ./contexts/ReduxContext.js
import { createContext } from "react";
const ReduxContext = createContext();
export default ReduxContext;
// ./index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import store from "./redux/store";
import ReduxContext from "./contexts/ReduxContext";
ReactDOM.render(
<React.StrictMode>
<ReduxContext.Provider value={store}>
<App />
</ReduxContext.Provider>
</React.StrictMode>,
document.getElementById("root")
);
// ./hooks/useReduxState.js
import { useContext, useEffect, useState } from "react";
import ReduxContext from "../contexts/ReduxContext";
export default function useReduxState() {
const store = useContext(ReduxContext);
const [state, setState] = useState(store.getState());
useEffect(() => {
const unsubscribe = store.subscribe(() => {
setState(store.getState());
});
return () => {
unsubscribe();
};
}, [store]);
return state;
}
// ./hooks/useReduxDispatch.js
import { useContext } from "react";
import ReduxContext from "../contexts/ReduxContext";
export default function useReduxDispatch() {
const store = useContext(ReduxContext);
return store.dispatch;
}
// ./components/TodoList.jsx
import useReduxState from "../hooks/useReduxState";
import todos from "../redux/reducers/todos";
export default function TodoList() {
const state = useReduxState();
return (
<ul>
{state.todos.map((todo) => {
return <li>{todo.text}</li>;
})}
</ul>
);
}
// ./components/TodoForm.jsx
import { useRef } from "react";
import useReduxDispatch from "../hooks/useReduxDispatch";
import { addTodo } from "../redux/actions";
export default function TodoForm() {
const inputRef = useRef();
const dispatch = useReduxDispatch();
return (
<div>
<input ref={inputRef} />
<button onClick={click}>μΆκ°</button>
</div>
);
function click() {
dispatch(addTodo(inputRef.current.value));
}
}
// ./App.js
import logo from "./logo.svg";
import "./App.css";
import { addTodo } from "./redux/actions";
import TodoList from "./components/TodoList";
import TodoForm from "./components/TodoForm";
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<TodoList />
<TodoForm />
</header>
</div>
);
}
export default App;
- react-redux μ°κ³ μ°κ²°νκΈ° (react-redux)
- Provider μ»΄ν¬λνΈλ₯Ό μ 곡ν΄μ€λλ€.
- connect ν¨μλ₯Ό ν΅ν΄ "컨ν
μ΄λ"λ₯Ό λ§λ€μ΄μ€λλ€.
- 컨ν μ΄λλ μ€ν μ΄μ state μ dispatch(μ‘μ ) λ₯Ό μ°κ²°ν μ»΄ν¬λνΈμ props λ‘ λ£μ΄μ£Όλ μν μ ν©λλ€.β
- κ·Έλ λ€λ©΄ νμν κ²μ ?
- μ΄λ€ state λ₯Ό μ΄λ€ props μ μ°κ²°ν κ²μΈμ§μ λν μ μ
- μ΄λ€ dispatch(μ‘μ ) μ μ΄λ€ props μ μ°κ²°ν κ²μΈμ§μ λν μ μ
- κ·Έ props λ₯Ό λ³΄λΌ μ»΄ν¬λνΈλ₯Ό μ μ
$ npm i react-redux
// ./index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import store from "./redux/store";
import { Provider } from "react-redux";
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
// ./container/todoistContainer.js
import { useSelector } from "react-redux";
import TodoList from "../components/TodoList";
function TodoListContainer() {
const todos = useSelector((state) => state.todos);
return <TodoList todos={todos} />;
}
export default TodoListContainer;
// ./comtianer/TodoFormContainer.js
import { useDispatch } from "react-redux";
import { addTodo } from "../redux/actions";
import TodoForm from "../components/TodoForm";
import { useCallback } from "react";
export default function TodoFormContainer() {
const dispatch = useDispatch();
const add = useCallback(
(text) => {
dispatch(addTodo(text));
},
[dispatch]
);
return <TodoForm add={add} />;
}
// ./components/TodoList.jsx
export default function TodoList({ todos }) {
return (
<ul>
{todos.map((todo) => {
return <li>{todo.text}</li>;
})}
</ul>
);
}
// ./components/TodoForm.jsx
import { useRef } from "react";
export default function TodoForm({ add }) {
const inputRef = useRef();
return (
<div>
<input ref={inputRef} />
<button onClick={click}>μΆκ°</button>
</div>
);
function click() {
add(inputRef.current.value);
}
}
// ./App.js
import logo from "./logo.svg";
import "./App.css";
import TodoListContainer from "./containers/TodoListContainer";
import TodoFormContainer from "./containers/TodoFormContainer";
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<TodoListContainer />
<TodoFormContainer />
</header>
</div>
);
}
export default App;
μ€λμ μΌκΈ°
redux react μ°κ²°νκΈ° μμ λ€μΌλ©΄μ λΈλ‘κ·Έμ μ΄μ¬ν μ 리νλ μ€μ μ¬μ§μ 첨λΆνλλ° κ°μκΈ° μλ°μ΄ λ¨κΈ° μμνκ³ λ무 λΆμνμ§λ§ μκ°λ½μ λ¨ΉμΌλ©΄μ κΈ°λ€λ Έλ€............................... κ·Όλ° νλ©΄μ΄ λ©μ·λ€. λ΄ μΈμμ΄ λ¬΄λμ‘λ€. μ λ§ λ¨Έλ¦¬κ° κ΅³μλ€. κ΅³μ λ¨Έλ¦¬λ‘ μκ° ν΄λΈκ² μλ‘κ³ μΉ¨................................... λ§Ήμ΄μ΄ λ΄κ° μ΄μ¬ν κΈ°λ‘ νλ κ²λ€μ΄ λ€ λ λΌκ°λ²λ Έλ€. μ§μ§ μμ°νκ³ λ무 νκ° λμ μ°μΌλ‘ λλ¬Όμ΄ λ¬λ€. λ μ μΈμλ€. μ§κΈλ λͺμλΆ λμ μΈμΌλ©΄μ λλλμ λ¨Έλ¦¬κ° μ§λμ§λμ°μ§λνλ€. ν μλ μ μ₯ κΈ°λ₯μ΄ μλ γ γ γ γΉλ₯Ό μλ§νκΈ° μμνλ€. κ·Όλ° μ μ λ§λ€μμκΉ λ€μ΄λ²λ μλλ°.............................. γ γ γ γΉλ₯Ό μ°λ λ΄κ° μλ§μ€λ¬μ κ³ λ Έμ μΌλ‘ λ°κΏκΉ μ§μ§νκ² κ³ λ―Όνλ€. κΉνλΈ μ°λ μ ν΄λμ μλ μ½λλ μκ³ ... ν¬λ§μ κ°μ§κ³ ctrl Z λ₯Ό λλ¬λ΄€μ§λ§ μ΄λ―Έ μ μ₯ν΄μ κ·Έλ°κ° (μμ§λ μ μ§ λͺ¨λ₯΄κ² λ€ λΆνλ€) κ± λ€λ‘κ°κΈ°κ° μ λλλ°...................γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ λͺμκ°λμ μμ λ€μκ² λ λΌκ°λκΉγ γ γ γ γ μλλ©΄ μ½λλ μκ³ ppt 볡λΆνλ € ν΄λ μμ λ΄μ©μ΄λ ν΄λΉ μ½λκ° λ€λ₯΄λλΌ.... λ³΅μ΅ νκ³ μΆμλ°...............................................γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ λ€μμ νλ‘μ νΈ μ§λ©΄μ λ€μ λ³΄κ³ μΆμλ°...γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ μνννγ νννν³γ νγ γ μ§μ§ λ€μ λ€μ μκ°μ΄ μμ΄μ.. μκ°μ΄ λ무 μ΄λ°ν λ μ΄μλ€..... μ νν μ΄λ΄ λ λμκ² μ΄λ° μλ ¨μ΄ μλ~ 머리λ₯Ό νννν λ―κ³ μΆλ€. μκ°μ΄ μμ§λ§ μ¬κΈ°μ μ΄κ±Έ μ°κ³ μλ μ΄μ λ μ§κΈ λκ° λ λΌκ°λ€... μ무 μκ°μ΄ λμ§ μκ³ μμ§κ° μλ€. λ°₯μ΄λ λ¨Ήκ³ ... κΈμͺ½μ΄ λ³΄κ³ .. ν λλ μ΄λ‘ν΄~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
μ§κΈ λ¨μμλ μ½λλ μμμ΄λ ppt κΈμ΄ λͺ¨μμ μ΄λ»κ² μμ΅νκΈ°λ νλ€. λ΄ μ½λκ° μλκ³ μ£Όμ μ²λ¦¬ ν κ²λ μμ΄μ Έμ μ°μ°νκΈ°λ νμ§λ§ λ μ§λκ° μΌμΈλ° μ°μ§κ² λ μνλ€κ³ μ§λκ° μ°Ύμμ λ΄ μμμ λ€μ΄μ£Όμ§λ λͺ»ν κ²μ΄λ€... ννν λ λ΄λ²λ΄ μ νκΈ°λ₯Ό!!!!!!!!!!!!!!! λ μ΄μ μ μ²κΈ° κ³΅λΆ νλ¬ κ°μΌκ² λ€ μΏ°νΌ λ€μμλ ν μ±ν°ν λ λ§λ€ μ μ₯νκ³ λ§ν μΌ............................................................................................................................................. κΉνλΈλ......................... ν κ±°μΌ λ.......................................................................................................................................................... λ λ무 μ¬νΌ
μΌκΈ° λ.
~ κ·Έ ν λ·μ΄μΌκΈ° ~
λ΄κ° μ 리νκ² μλμ΄μ λμΉ λΆλΆμ΄ μμκΉλ΄ μ°μ°νκΈ°λ νκ³ μ€μν λ΄μ©μ΄λ 볡μ΅λ ν κ²Έ λ€μ μ 리νλ κ²λ λμμ§ μλ€κ³ μκ°ν΄μ μμ λ λΌκ° λΆλΆλ§ λ€μ λ€μλ€! λ§μμ΄ νΈνλ€ π μμ μ΄ κ±° 보λκΉ γΉγ λ©λΆμλ κ±° κ°μγ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ γ ...^^ νν« μ€λμ κ΅ν: μ§μ¦λ΄κ³ νλ΄κ³ μμ± ν μκ°μ μ¬λΉ λ₯΄κ² λ€μ νλκ² μκ°(++κ°μ )μ΄ λ μ μ½λλ€. λ.
'π¬ > γ γ γ γ γ γ μ±λ¦°μ§' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
43, 44μΌμ°¨ (0) | 2022.03.26 |
---|---|
42μΌμ°¨ (0) | 2022.03.26 |
useMemo μ useCallback μ 무μμ΄ λ€λ₯Έ κ²μΈκ°...... (0) | 2022.03.25 |
40μΌμ°¨ (0) | 2022.03.24 |
39μΌμ°¨ (0) | 2022.03.24 |