// index.js
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
import { Provider } from "react-redux";
import store from "./store";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
);
// App 컴포넌트와 store를 연결시킨다. -- Provider
//App.js
import React from "react";
import { Routes, Route } from "react-router";
import Detail from "./routes/Detail";
import Home from "./routes/Home";
export default function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/:id" element={<Detail />} />
</Routes>
);
}
// ❗️store.js
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;
// Home.js
import { useState } from "react";
import { connect } from "react-redux";
function Home(props) {
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>
</>
)
}
function mapStateToProps(state, ownProps) {
console.log(state, ownProps);
};
function mapDispatchToProps(dispatch, ownProps) {
return {
addToDo: (text) => dispatch(actionCreators.addToDo(text))
}
}
// redux-react 에서 connect는 컴포넌트와 store를 연결시켜준다.
export default connect(mapStateToProps, mapDispatchToProps)(Home);
mapStateToProps()
를 통해서 store.js에 저장된 state 값을 가져온다.mapDispatchToProps()
를 통해서 액션함수를 가져온다.useSelector, useDispatch의 사용
❗️mapDispatchToProps()
, mapStateToProps()
, connect()
사용 대신 useSelector
, useDispatch
를 사용해서 코드를 간략하게 작성할 수 있다. (⭐️요즘 더 많이 쓰이는 코드이다.)
// Home.js
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { addToDo, deleteToDo } from "../store";
import { Link } from "react-router-dom";
function Home() {
const [text, setText] = useState("");
const todo = useSelector((state) => state);
console.log(todo); // 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>
{todo.map((item) => (
<li key={item.id}>
<Link to={`/${item.id}`}>
{item.text}
</Link>
<button onClick={() => dispatch(deleteToDo(item.id))}>
DELETE
</button>
</li>
))}
</ul>
</>
);
}
export default Home;