[๊ฐœ์ธ๊ณผ์ œ]

[React] lv2๊ณผ์ œ - ํŽ˜์ด์ง€ ๋žœ๋”๋ง

Lethargin 2023. 6. 27. 00:35

src > Components > ListsTobeSorted.jsx

export const ListsToBeSorted = () => {
  //
  const todos = useSelector((state) => state.todos);
  const dispatch = useDispatch();

  //
  const changeStatusHandler = (def) => {
    dispatch(toggleStatusTodo(def));
  };

  const deleteStatusHandler = (abc) => {
    dispatch(deleteTodo(abc));
  };

  return (
    <>
      <div className="working">
        <h2>Working๐Ÿ”ฅ</h2>
        <div className="working-container">
          {todos
            .filter((todo) => todo.isDone === false)
            .map(function (todo) {
              return (
                <div key={todo.id}>
                  <h5>{todo.title}</h5>
                  <br />
                  <p>{todo.content}</p>
                  <br />
                  <p>์™„๋ฃŒ์—ฌ๋ถ€: {todo.isDone.toString()}</p>
                  <button
                    onClick={() => changeStatusHandler(todo.id)}

                    // () => {
                    //   dispatch(
                    //     {
                    //       type: TOGGLE_STATUS_TODO,
                    //       payload: "todo.id", =>๋Œ€์‹  ์œ„์—์„œ๋Š” def๋กœ ๋”ฐ๋กœ ๋บŒ
                    //     }
                    //   )
                    // }
                  >
                    ์™„๋ฃŒ
                  </button>
                  <button
                    onClick={() => deleteStatusHandler(todo.id)}

                    // () => {
                    //   dispatch(
                    //     {
                    //       type: DELETE_TODO,
                    //       payload: "todo.id", =>๐Ÿฆ‘ํ•จ์ˆ˜๋ฅผ ๋”ฐ๋กœ ๋นผ๊ฒŒ ๋˜๋ฉด, payload๋กœ ๋„ฃ์€ todo.id๋ฅผ ์ธ์‹ํ•˜์ง€ ๋ชปํ•ด์„œ abc๋กœ ๋ฐ”๊ฟˆ. but ๊ฒฐ๊ตญ abc = todo.id์ž„
                    //     }
                    //   )
                    // }
                  >
                    ์‚ญ์ œ
                  </button>
                  {/* ์ƒ์„ธ๋ณด๊ธฐ */}
                  {/* <Link to="/1">์ƒ์„ธ๋ณด๊ธฐ</Link> */}
                  {/* ๐Ÿฆ‘/${todo.id}๋Š” todo ๊ฐ์ฒด์˜ id ๊ฐ’์„ ํฌํ•จํ•œ ๊ฒฝ๋กœ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, todo.id๊ฐ€ 9d33d690-48ff-45e3-88ba-e8b3d872433b์ธ ๊ฒฝ์šฐ, ์ƒ์„ฑ๋˜๋Š” ๊ฒฝ๋กœ๋Š” /9d33d690-48ff-45e3-88ba-e8b3d872433b๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. */}
                  <Link to={`/${todo.id}`}>์ƒ์„ธ๋ณด๊ธฐ</Link>
                </div>
              );
            })}
        </div>
      </div>

      <div className="done">
        <h2>Done๐ŸŽ‰</h2>
        <div className="done-container">
          {/* {todos
            .filter((todo) => todo.isDone === true)
            .map(function (todo) {
              return todo.isDone ? (
                <div key={todo.id}>
                  <h5>{todo.title}</h5>
                  <br />
                  <p>{todo.content}</p>
                  <br />
                  <p>์™„๋ฃŒ์—ฌ๋ถ€: {todo.isDone.toString()}</p>
                  <button onClick={() => changeStatusHandler(todo.id)}>
                    ์™„๋ฃŒ์ทจ์†Œ
                  </button>
                  <button onClick={() => deleteStatusHandler(todo.id)}>
                    ์‚ญ์ œ
                  </button>
                </div>
              ) : null;
            })} */}
          {todos
            .filter((todo) => todo.isDone === !false)
            .map(function (todo) {
              return (
                <div key={todo.id}>
                  <h5>{todo.title}</h5>
                  <br />
                  <p>{todo.content}</p>
                  <br />
                  <p>์™„๋ฃŒ์—ฌ๋ถ€: {todo.isDone.toString()}</p>
                  <button onClick={() => changeStatusHandler(todo.id)}>
                    ์™„๋ฃŒ์ทจ์†Œ
                  </button>
                  <button onClick={() => deleteStatusHandler(todo.id)}>
                    ์‚ญ์ œ
                  </button>
                  <Link to={`/${todo.id}`}>์ƒ์„ธ๋ณด๊ธฐ</Link> ๐Ÿ‘ˆ
                </div>
              );
            })}
        </div>
      </div>
    </>
  );
};

์ด ํŒŒ์ผ์—์„œ์˜ ์ฝ”๋“œ(1)๋ž‘

<Link to={`/${todo.id}`}>์ƒ์„ธ๋ณด๊ธฐ</Link>

 

src > shared > Router.jsx

import React from "react";
// 1. react-router-dom์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์•„๋ž˜ API๋“ค์„ import ํ•ฉ๋‹ˆ๋‹ค.
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "pages/Home";
import Details from "pages/Details";

// 2. Router ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
//BrowserRouter๋ฅผ Router๋กœ ๊ฐ์‹ธ๋Š” ์ด์œ ๋Š”,
//SPA์˜ ์žฅ์ ์ธ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊นœ๋นก์ด์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค!
const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/:abcdef" element={<Details />} />  ๐Ÿ‘ˆ
        {/* ๐Ÿฆ‘"/:id"๋กœ, ๋™์ ์ธ id๊ฐ’์„ ์ „๋‹ฌ */}
      </Routes>
    </BrowserRouter>
  );
};

export default Router;

์ด ํŒŒ์ผ์—์„œ์˜ ์ฝ”๋“œ(2)๋ž‘ 

<Route path="/:abcdef" element={<Details />} />

์„œ๋กœ ์–ด๋–ป๊ฒŒ ์—ฐ๊ฒฐ์ด ๋˜๋Š”์ง€ ์ž˜ ์ดํ•ด๊ฐ€ ์•ˆ๊ฐ.

 


 โถ <Link to={`/${todo.id}`}>์ƒ์„ธ๋ณด๊ธฐ</Link> ์—์„œ์˜ to๊ฐ€

โท  <Route path="/:abcdef" element={<Details />} /> ์—์„œ์˜ path๋ฅผ ์˜๋ฏธ. ๋”ฐ๋ผ์„œ, ๋ชฉ์ ์ง€๋Š” <Details />์ด๋ฉฐ, ์ถ”ํ›„ ๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜์ธ :abcdef์˜ ๊ฐ’์„ useParams()๋ฅผ ํ†ตํ•ด ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์Œ.

 

src > pages > Details.jsx

import React from "react";
import { useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";

const Details = () => {
  // const params = useParams(); ๐Ÿ‘ˆ
  // console.log("useParams๋ฅผ ์“ฐ๋ฉด, todo.id๊ฐ’์„ ๊ฐ์ฒด๋กœ ๋ฐ›์•„์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค", params); ๐Ÿ‘ˆ

  //
  const { abcdef } = useParams(); ๐Ÿ‘ˆ
  console.log("๋„˜๊ฒจ๋ฐ›์€ id", abcdef); ๐Ÿ‘ˆ

  //์ด์ „ ํ™”๋ฉด์œผ๋กœ
  const navigate = useNavigate();

  //๐Ÿฆ‘todos.filter์˜ ๋ฐ˜ํ™˜๋œ ๋ฐฐ์—ด : ์š”์†Œ๊ฐ€ 1๊ฐœ์งœ๋ฆฌ์ธ [0] ๋ฐฐ์—ด์ž„. ๋”ฐ๋ผ์„œ ๋ช…์‹œํ•ด์ค˜์•ผ ํ•จ
  const todos = useSelector((state) => state.todos);

  // todos = [
  //   {id:000},
  //   {id: 001},
  // ]

  const todo = todos.filter((todo) => todo.id === abcdef)[0]; //๐Ÿฆ‘โ“โ“โ“ [0]์„ ์•ˆํ•ด์ฃผ๋ฉด ํ™”๋ฉด์— id ์ถœ๋ ฅ์ด ์•ˆ๋จ
  //
  return (
    <div>
      {todo.id}
      <br />
      {todo.title}
      <br />
      {todo.content}
      <br />
      {todo.isDone.toString()}
      <br />
      <button onClick={() => navigate("/")}>์ด์ „ ํ™”๋ฉด์œผ๋กœ</button>
    </div>
  );
};

export default Details;

 


+) ํŒŒ์ผ๊ฐ„ ๊ตฌ์กฐ

 

โถIndex.js

root.render(
  //โทApp์„ Provider๋กœ ๊ฐ์‹ธ์ฃผ๊ณ , configStore์—์„œ export default ํ•œ store๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. => โธapp.jsx์—์„œ ์ด์ œ useSelector๋กœ store์˜ ๊ฐ’ (state)๋ฅผ ๊บผ๋‚ด์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋จ
  <Provider store={store}>
    <App />
  </Provider>
);

โทApp.jsx

function App() {
  //์ฝ˜์†”๊ฐ’ ๋น„๊ต
  const todos = useSelector(function (state) {
    return state.todos;
  });
  console.log("state.todos์˜ ์ฝ˜์†”๊ฐ’์€ ๋ฐฐ์—ด", todos);

  console.log(
    "state์˜ ์ฝ˜์†”๊ฐ’์€ ๊ฐ์ฒด",
    useSelector((state) => state)
  );

  return (
    <div>
      <Router />
    </div>
  );
}

โธRouter.jsx     

const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/:abcdef" element={<Details />} />
        {/* ๐Ÿฆ‘"/:id"๋กœ, ๋™์ ์ธ id๊ฐ’์„ ์ „๋‹ฌ */}
      </Routes>
    </BrowserRouter>
  );
};

โนHome.jsx

function Home() {
  return (
    <div>
      <Form />
      <ListsToBeSorted />
    </div>
  );
}

=> ์‹ค์ œ ํŽ˜์ด์ง€๋Š” Home.jsx (⊃Form.jsx, ListsToBeSorted) & Details.jsx์ด๊ณ ,

     index.js ⊃ app.jsx ⊃ Router.jsx ๋Š” ๊ธฐ๋Šฅ๋งŒ ํ•œ๋‹ค๊ณ  ๋ด์•ผํ•  ๋“ฏ