Redux | NomardCoder
* React Redux
(0. Setup)
- redux는 vanillaJS part에서 이미 설치했음 (package확인)
- react-redux, react-router-dom 설치하기 (npm istall react-redux react-router-dom)
1. react, router 로 todo 만들기
App.js에 router로 Home, Detaile 페이지 생성
Router
import React from "react";
import { HashRouter as Router, Route } from "react-router-dom";
import Home from "../routes/Home";
import Detail from "../routes/Detail";
function App() {
return (
<Router>
<Route path="/" exact component={Home}></Route>
<Route path="/:id" component={Detail}></Route>
</Router>
);
}
export default App;
React
Home 페이지에 todo form
import React, { useState } from "react";
function Home() {
const [text, setText] = useState("");
function onChange(e) {
setText(e.target.value);
}
function onSubmit(e) {
e.preventDefault();
setText("");
}
return (
<>
<h1>To Do</h1>
<form onSubmit={onSubmit}>
<input type="text" value={text} onChange={onChange} />
<button>Add</button>
</form>
<ul></ul>
</>
);
}
export default Home;
Redux
store 생성
import { createStore } from "redux";
const ADD = "ADD";
const DELETE = "DELETE";
export const addToDo = (text) => {
return {
type: ADD,
text,
};
};
export const deletToDo = (id) => {
return {
type: DELETE,
id,
};
};
const reducer = (state = [], action) => {
switch (action.type) {
case ADD:
return [...state, { text: action.text, id: Date.now() }];
case DELETE:
return state.filter((toDo) => toDo.id !== action.id);
default:
return state;
}
};
const store = createStore(reducer);
export default store;
2. react + redux
- connecting the Store
react는 모든 페이지를 render하지 않고 변화되는 부분만 render 된다
index에서 내 application 연결하기
//index.js
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
import store from "./store";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
3. redux - connect
conntect - components들을 store에 연결시켜줌
- store로부터 state 가져올 수 있게 Home과 store 연결
- conntect는 두 개의 argument를 가짐 (state, dispatch)
3-1) connect/state - redux state로부터 정보 가져오기 ( getState() -> mapStateToProps() )
Connect: Extracting Data with mapStateToProps | React Redux
Connect: Extracting Data with mapStateToProps
react-redux.js.org
//Home.js
function getCurrentState(state, ownProps) {
console.log(state, ownProps);
}
export default connect(getCurrentState)(Home);
- state - store로부터 가져온 state
- ownProps - Home에게 준 props
+) ownProps 통해 원하는 props를 전달할 수 있다.
내가 이해한 바로 정리> provider의 store로 내부 components와 store을 연결시켜서 사용 → store과 component를 연결하기 위해 mapStateToProps 함수 사용→ 연결로 store로부터 state를 가져올 수 있음 (store.getState() 역할과 비슷)
3-2) connect/dispatch - ( dispatch() -> mapDispatchToProps() )
- dispatch - store로부터 전달된 dispatch
- ownProps - Home에게 준 props
Connect: Dispatching Actions with mapDispatchToProps | React Redux
Connect: Dispatching Actions with mapDispatchToProps
react-redux.js.org
import React, { useState } from "react";
import { connect } from "react-redux";
import { addToDo } from "../store";
function Home({ toDos, dispatch }) {
const [text, setText] = useState("");
function onChange(e) {
setText(e.target.value);
}
function onSubmit(e) {
e.preventDefault();
setText("");
dispatch(addToDo(text));
}
return (
<>
<h1>To Do</h1>
<form onSubmit={onSubmit}>
<input type="text" value={text} onChange={onChange} />
<button>Add</button>
</form>
<ul>{JSON.stringify(toDos)}</ul>
</>
);
}
//mapStateToProps
function mapStateToProps(state) {
return {
toDos: state,
};
}
function mapDispatchToProps(dispatch) {
return { dispatch };
}
export default connect(mapStateToProps, mapDispatchToProps)(Home);
↓ `addToDo`라는 props 만들어서 사용하기 (refactoring)
//store.js
export const actionCreators = {
addToDo,
deletToDo,
};
//Home.js
import React, { useState } from "react";
import { connect } from "react-redux";
import { actionCreators } from "../store";
function Home({ toDos, addToDo }) {
const [text, setText] = useState("");
function onChange(e) {
setText(e.target.value);
}
function onSubmit(e) {
e.preventDefault();
addToDo(text);
setText("");
}
return (
<>
<h1>To Do</h1>
<form onSubmit={onSubmit}>
<input type="text" value={text} onChange={onChange} />
<button>Add</button>
</form>
<ul>{JSON.stringify(toDos)}</ul>
</>
);
}
//mapStateToProps
function mapStateToProps(state) {
return {
toDos: state,
};
}
function mapDispatchToProps(dispatch) {
return {
addToDo: (text) => dispatch(actionCreators.addToDo(text)),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Home);
- Home component는 직접 dispatch나 action Creators를 처리할 필요 없이, props로 전달해주기
4. toDo 출력, delete 기능
//Home.js
<ul>
{toDos.map((toDo) => (
<ToDo {...toDo} key={toDo.id} />
))}
</ul>
- mapStateToProps()로 state가져와서 toDo에 출력하기
//toDo.js
import React from "react";
import { connect } from "react-redux";
import { actionCreators } from "../store";
function ToDo({ text, onBtnClick }) {
return (
<li>
{text} <button onClick={onBtnClick}>btn</button>
</li>
);
}
function mapDispatchToProps(dispatch, ownProps) {
return {
onBtnClick: () => dispatch(actionCreators.deletToDo(ownProps.id)),
};
}
export default connect(null, mapDispatchToProps)(ToDo);
- mapDispatchToProps()로 delete기능
'Redux' 카테고리의 다른 글
Redux Toolkit (0) | 2021.05.05 |
---|---|
[Redux 강의노트] Redux Middleware | redux-saga (0) | 2021.01.13 |
[Redux 강의노트] Redux Middleware | logger, thunk (0) | 2021.01.09 |
[Redux강의노트] Redux (0) | 2021.01.03 |
VanillaJS → Redux | Redux 101 (1/2) (0) | 2020.11.18 |