본 글은 노마더코더의 초보자를 위한 리덕스 101 강의를 들으며 작성한 글입니다.
개인적으로 이해한 내용이 들어가있어 부정확한 내용이 적힐 수 있습니다. 지적 바랍니다.
이제 우리는 React에서 Redux를 사용하고자 한다.
Redux에서는 기존에 제공하는 Redux 라이브러리에 react-redux라는 라이브러리를 추가로 제공해준다.
npm install react-redux
import React from "react";
import ReactDOM from "react-dom";
import App from "./conponents/App";
ReactDOM.render(
<App />, document.getElementById("root")
);
index.js
import React from "react";
import { HashRouter as Router, Routes, Route } from "react-router-dom";
import Home from "../routes/Home";
import Detail from "../routes/Detail";
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="/:id" element={<Detail />}></Route>
</Routes>
</Router>
);
}
export default App;
App.js
import React, { useState } from "react";
function Home() {
const [text, setText] = useState("");
function onChange(e) {
setText(e.target.value);
}
function onSubmit(e) {
e.preventDefault();
console.log(text);
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;
Home.js
Setting
import { createStore } from "redux";
const ADD = "ADD";
const DELETE = "DELETE";
export const addToDo = (text) => {
return {
type: ADD,
text,
};
};
export const deleteToDo = (id) => {
return {
type: DELETE,
id,
};
};
const reducer = (state = [], action) => {
switch (action.type) {
case ADD:
return [{ text: action.text, id: Date.now() }, ...state];
case DELETE:
return state.filter((toDo) => toDo.id !== action.id);
default:
return state;
}
};
const store = createStore(reducer);
export default store;
store.js
먼저 store.js를 통해 vanilla js에서 redux와 비슷하게 기능을 구현해준다.
ADD와 DELETE를 통해 TO DO 리스트에 변화가 생기면 우리는 이를 감지해 React에서 rerendering 해주고 싶을 것이다.
Vanilla JS에서 우리는 store의 subscribe()라는 함수를 통하여 state의 change를 감지하고
paintToDo 함수를 실행시켜 state의 변화를 다시 그려주었다.
반면, React에서는 subscribe함수가 아니라 react-redux 라이브러리를 이용하여 이를 진행할 것이다.
이를 위해서 react-redux의 Provider가 필요하다.
Provider
import React from "react";
import ReactDOM from "react-dom";
import App from "./conponents/App";
import { Provider } from "react-redux";
import store from "./store";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
index.js
Provider는 React를 Redux의 Store와 연동할 수 있도록 해주는 컴포넌트이다.
Provider는 store 속성을 가지고 Provider 태그로 감싸진 컴포넌트와 store 속성의 store가 연동된다.
위 코드를 보면 Provider를 통해 index.js에서 내 App 컴포넌트와 store를 연동하였다.
connect
Connect 역시도 컴포넌트와 Store를 연동해주는 함수이지만,
쉽게말해, Provider는 State의 변화를 감지해 React를 Rerendering하도록 연동하는 방법이라면(subscribe)
connect는 getState, dispatch와 같은 함수를 컴포넌트와 연동하는 방법이다.
예를 들어 ToDo list가 Home 컴포넌트에서 불러와 그려진다고 하면
Home 컴포넌트는 일단 store에서 ToDo list(State)를 불러와야 그릴 수 있을 것이다.
Vanilla JS에서는 getState, dispatch 함수를 사용했지만 React에서는 connect 함수를 사용한다.
connect는 둘 중 하나의 arguments를 가질 수 있다.
- state(getState)
- dispatch
지금은 getState와 같은 기능이 필요하므로 state를 argument로 가질 것이다.
import React, { useState } from "react";
import { connect } from "react-redux";
function Home({ toDos }) {
...
}
function getCurrentState() {}
export default connect(getCurrentState)(Home);
Home.js
getCurrentState라는 함수로 connect로 Home에 연결해주면 이 함수가 Store로부터 Home에 state를 가져다 준다.
redux 문서에서는 getCurrentState라는 함수를 mapStateToProps라고 부른다. 고쳐보자.
mapStateToProps
import React, { useState } from "react";
import { connect } from "react-redux";
function Home(props) {
console.log(props);
...
}
function mapStateToProps(state, ownProps) {
//console.log(state, ownProps);
return {test : "hello"};
}
export default connect(mapStateToProps)(Home);
Home.js
mapStateToProps는 state와 props 2개의 arguments를 가질 수 있다.
- state는 Redux store로부터 온 Redux store가 가지고 있는 state이다.
- ownProps는 React-Router로부터 주어진 component의 props이다. (이 경우에는 Home의 props)
mapStateToProps를 사용한다는 것은 getState, 즉 Redux Store로부터 State를 가져오고 싶다는 뜻이다.
가져왔다면 가져온 State를 Component의 Props에 넣는다.
예를 들어 mapStateToProps 함수는 { test: "hello" } 라는 객체를 return 해주고 있는데
Home에서 props를 출력해보면 기존 props 외에 { test: "hello" }가 들어가 있음을 확인할 수 있다.
그렇다면 { test: "hello" }가 아니라 state를 return해준다면 component의 props에 state가 추가된다고 생각할 수 있다.
즉, Home은 mapStateToProps함수로 props를 통해 Redux의 state를 받아올 수 있는 것이다.
import React, { useState } from "react";
import { connect } from "react-redux";
function Home({ toDos }) {
...
}
function mapStateToProps(state) {
return { toDos: state };
}
export default connect(mapStateToProps)(Home);
Home.js
'Frontend > 상태관리' 카테고리의 다른 글
[Redux Toolkit] createAction (0) | 2022.01.14 |
---|---|
[React-Redux] mapDispatchProps (0) | 2022.01.14 |
[Redux] NEVER MUTATE STATE (0) | 2022.01.13 |
[Redux] Subscribe (0) | 2022.01.13 |
[Redux] Actions - Dispatch (0) | 2022.01.13 |