๐ŸŽˆRedux + React(without toolkit)

Coaspeยท2021๋…„ 2์›” 25์ผ
0
post-thumbnail

๐Ÿ“ƒ 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์€ react-redux๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด store์„ ์ œ๊ณต ๋ฐ›๋Š”๋‹ค.
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

๐Ÿ“ƒ store.js

import { createStore } from "redux";
const ADD = "ADD";
const DELETE = "DELETE";

  // ์•ก์…˜ ์ƒ์„ฑ ํ•จ์ˆ˜ 1
const addToDo = (text) => {
  return {
    type: ADD,
    text,
  };
};

  // ์•ก์…˜ ์ƒ์„ฑ ํ•จ์ˆ˜ 2
const deleteToDo = (id) => {
  return {
    type: DELETE,
    id: parseInt(id),
  };
};

  // ์˜ค์ง reducer๋กœ๋งŒ state์— ๋ณ€ํ™”๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋‹ค.
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 const actionCreators = {
  addToDo,
  deleteToDo,
};
export default store;

๐Ÿ“ routes

๐Ÿ“ƒ Home.js

import React from "react";
import { useState } from "react";
import { connect } from "react-redux"; // react component์™€ store์„ ์—ฐ๊ฒฐ์‹œ์ผœ์„œ state์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ dispatchํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.
import { actionCreators } from "../store";
import ToDo from "../components/ToDo";

function Home({ toDos, addToDo }) {
  // { toDos } => toDos = props.toDos
  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>
        {toDos.map((toDo) => (
          <ToDo {...toDo} key={toDo.id} />
        ))}
      </ul>
    </>
  );
}

// Redux state๋ฅผ component์˜ props๋กœ ์ „๋‹ฌํ•œ๋‹ค.
function mapStateToProps(state) {
  return { toDos: state };
}
// Component์˜ props๋กœ store.dispatch(์•ก์…˜์ƒ์„ฑํ•จ์ˆ˜ or ์•ก์…˜)๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.
function mapDispatchToProps(dispatch) {
  return {
    addToDo: (text) => dispatch(actionCreators.addToDo(text)),
  };
}
export default connect(mapStateToProps, mapDispatchToProps)(Home);
// mapStateToProps ์ด์šฉํ•ด์„œ state๋ฅผ ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์ด๋‹ค.
// connect()๋Š” ํ•ด๋‹น component๋กœ ๋ณด๋‚ด๋Š” props์— ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ด ์ค€๋‹ค.
// => return ๊ฐ’์ด props๋กœ ์ถ”๊ฐ€๋œ๋‹ค.

๐Ÿ“ƒ Detail.js

import React from "react";
import { useParams } from "react-router-dom";
import { connect } from "react-redux";

function Detail({ toDo }) {
  // const id = useParams();
  return (
    <>
      <h1>{toDo?.text}</h1>
      <h5>Created at : {toDo?.id}</h5>
    </>
  );
}

function mapStateToProps(state, ownProps) {
  const {
    match: {
      params: { id },
    },
  } = ownProps; // id = ownProps.match.params.id
  return { toDo: state.find((toDo) => toDo.id === parseInt(id)) }; // ์ด state๋Š” store์— ์žˆ๋Š” state์ด๋‹ค.
}

export default connect(mapStateToProps, null)(Detail);

๐Ÿ“ components

๐Ÿ“ƒ App.js

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" exact component={Detail}></Route>
    </Router>
  );
}

export default App;

๐Ÿ“ƒ ToDo.js

import React from "react";
import { connect } from "react-redux";
import { actionCreators } from "../store";
import { Link } from "react-router-dom";

function ToDo({ text, onBtnClick, id }) {
  return (
    <li>
      <Link to={`/${id}`}>
        {text} <button onClick={onBtnClick}>DEL</button>
      </Link>
    </li>
  );
}

function mapDispatchToProps(dispatch, ownProps) {
  return {
    // ํ•จ์ˆ˜ ํ˜•ํƒœ๋กœ ํ‘œ๊ธฐํ•ด์•ผ ํ•œ๋‹ค.
    onBtnClick: () => dispatch(actionCreators.deleteToDo(ownProps.id)),
  };
}

export default connect(null, mapDispatchToProps)(ToDo);
profile
https://github.com/Coaspe

0๊ฐœ์˜ ๋Œ“๊ธ€