#3 REACT REDUX
#3.0 Setup
REACT로 기본 세팅
react, react router dom 설치 & 세팅
#3.1 Connecting the Store
전에 진행한 store, reducer, dispatcher, action 내용 추가
react로 연결하는 과정에서 Provider 사용
코드
// 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" const root = ReactDOM.createRoot(document.getElementById("root")) root.render( <Provider store={store}> <App /> </Provider> )
#3.2 mapStateToProps
Connect & mapStateToProps를 사용해 state를 컴포넌트에 연결하는 과정
connect - return 내용을 컴포넌트의 prop에 추가한다.
mapStateToProps(state, props)
(* Hook - useSelector()로 state를 가져올 수 있음) 참고
mapStateToProps = useSelector = getState state를 가져오는 역할
코드
// Home.js import React, { useState } from "react"; import { connect } from "react-redux"; function Home({ toDos }) { 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>{JSON.stringify(toDos)}</ul> </> ); } function mapStateToProps(state) { return { toDos: state }; } export default connect(mapStateToProps)(Home);
#3.3 mapDispatchToProps
mapDispatchToProps을 사용해 dispatch 기능을 수행한다.
but 최근에는 connect와 mapStateToProps, mapDispatchToProps를 사용하지 않고
Hooks를 사용해 useDispatch, useSelector를 사용한다.
코드
// 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> </> ); } function mapStateToProps(state) { return { toDos: state }; } function mapDispatchToProps(dispatch) { return { addToDo: (text) => dispatch(actionCreators.addToDo(text)) }; } export default connect(mapStateToProps, mapDispatchToProps)(Home);
수정 코드
// Home.js import React, { useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { addToDo } from "../store" function Home() { const [text, setText] = useState(""); const toDos = useSelector((state)=>state) const dispatch = useDispatch() function onChange(e) { setText(e.target.value); } function onSubmit(e) { e.preventDefault(); dispatch(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> </> ); } export default Home;
#3.4 Deleting To Do
onClick 함수를 만들어 deleteToDo함수를 디스패치 할 수 있도록 만들었다.
강의 내용이 아닌 useDispatch를 사용해 생각보다 시간이 더 소요됐다.
그래도 막히는 부분을 찾아가면서 해결하니 성장한 기분이 든다.
코드
// Home.js import React, { useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import ToDo from "../components/ToDo"; import { addToDo, deleteToDo } from "../store" function Home() { const [text, setText] = useState(""); const toDos = useSelector((state)=>state) const dispatch = useDispatch() function onChange(e) { setText(e.target.value); } function onSubmit(e) { e.preventDefault(); dispatch(addToDo(text)) setText(""); } const onClick = (e) => { dispatch(deleteToDo(e)) } return ( <> <h1>To Do</h1> <form onSubmit={onSubmit}> <input type="text" value={text} onChange={onChange} /> <button>ADD</button> </form> <ul> {toDos.map(toDo => ( <ToDo {...toDo} id={toDo.id} onClick={onClick} key={toDo.id} /> ))} </ul> </> ); } export default Home; // ToDo.js import React from "react"; function ToDo({ text, id, onClick }) { return ( <li> {text} <button id={id}onClick={() => onClick(id)}>❌</button> </li> ); } export default ToDo;
#3.5 Detail Screen
(+ 추가 개념) /id Detail 페이지에서 상태 확인하기
코드
//Detail.js import React from "react"; import {useSelector} from "react-redux" import { useParams } from "react-router-dom"; function Detail() { const toDos = useSelector((state) => state); const doId = useParams().id; const toDoText=toDos.find((todo)=>todo.id === parseInt(doId)) return ( <> <div>{toDoText?.text}</div> <div>User ID:{toDoText?.id}</div> </> ) } export default Detail;
#3.6 Introduction
+ LocalStorage에 저장하기 구현
store.js - persistReducer, combineReducers
index.js - PersistGate
참고 참고2 참고3 다른사람완성본 - 나도 CSS까지 적용해보자 !
코드
// store.js import { combineReducers, createStore } from "redux"; import storage from "redux-persist/lib/storage"; import { persistReducer } from "redux-persist"; const persistConfig = { key:"todo", //localStorage에 저장될 key값 storage:storage }; 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: state.length }, ...state]; case DELETE: return state.filter((toDo) => toDo.id !== action.id); default: return state; } }; const allReducer = combineReducers({ reducer }); const store = createStore(persistReducer(persistConfig, allReducer)); export default store; ///////////////////////////////////// // index.js import React from "react"; import { createRoot } from "react-dom/client"; import { Provider } from "react-redux"; import App from "./components/App"; import store from "./store"; import { persistStore } from "redux-persist"; import { PersistGate } from "redux-persist/integration/react"; const rootElement = document.getElementById("root"); const root = createRoot(rootElement); const persistor = persistStore(store); root.render( <Provider store={store}> <PersistGate loading={null} persistor={persistor}> <App /> </PersistGate> </Provider> );
Last updated
Was this helpful?