今天我們要完成 homePage 的一部分功能,跟 todo 有關的部分,其實鐵人賽也到尾聲了,我要誠實的跟大家說,在鐵人賽的期間確定無法完成這個專案,不過也沒關係,在努力一下。
我寫了 26 篇,卻一直忘記一件事,今天就來跟大家說一下,其實我習慣會把我要做的事情一項一項寫下來,例如這樣 :
// 彈跳視窗
// 加入 list
// 把一個 todo 放到釘選位置
// 思考要釘選哪一種 todo
偷偷推薦一個我自己很喜歡的 vscode 套件 :Comment Anchors,我很常使用它來標記我的段落,也包含我自己接下來想寫的 code。
決定要做的事之後,首先,把 slice 引入進來之後,使用 Selector 來取得 state,中間 :
...
import { useAppSelector, useAppDispatch } from "../redux/hooks";
import {
  selectModalIsOpen,
  openModal,
  closeModal,
} from "../redux/modalSlice/modalSlice";
import { selectList, addTodo } from "../redux/todoSlice/todoSlice";
...
// const [isOpen, setIsOpen] = useState(false);
const isOpen = useAppSelector(selectModalIsOpen);
const list = useAppSelector(selectList);
console.log("list", list, "isOpen", isOpen);
...
新增一個 home 資料夾,HomePage 放進來,把報錯清除,之後就先無腦的把 TodoModal 複製一份變成 HomeModal,相同的 code 靜待下一次重購的時候處理,記得從 homePage 傳入 必要的 props 喔 :
HomeModal.tsx
import React from "react";
import Modal from "../../components/Modal";
type Props = {
  isOpen?;
  closeModal;
  onSubmit;
  register;
  handleSubmit;
  reset;
};
const HomeModal: React.FC<Props> = ({
  isOpen,
  closeModal,
  onSubmit,
  register,
  handleSubmit,
  reset,
}) => {
  return (
    <Modal isOpen={isOpen}>
      <div className="flex justify-end">
        <span
          className="
          font-medium
          cursor-pointer 
          inline-block 
          bg-gray-200 
          w-[24px] text-center rounded"
          onClick={closeModal}
        >
          X
        </span>
      </div>
      <div className="py-12 flex flex-col justify-center items-center">
        <h2 className="text-2xl font-bold">新增待辦</h2>
        <div className="mt-8">
          <form onSubmit={handleSubmit(onSubmit)}>
            <div className="grid grid-cols-1 gap-[8px] w-[340px]">
              <label className="block ">
                <span className="text-gray-700">標題</span>
                <input
                  type="text"
                  className="
                    mt-1
                    block
                    w-full
                    rounded-md
                    bg-gray-100
                    border-transparent
                    focus:border-gray-500 focus:bg-white focus:ring-0
                  "
                  {...register("title", { required: true })}
                />
              </label>
              <label className="block">
                <span className="text-gray-700">時間</span>
                <input
                  type="date"
                  className="
                    mt-1
                    block
                    w-full
                    rounded-md
                    bg-gray-100
                    border-transparent
                    focus:border-gray-500 focus:bg-white focus:ring-0
                  "
                  {...register("time")}
                  value="2018-07-22"
                />
              </label>
              <label className="block">
                <span className="text-gray-700">詳情描述</span>
                <textarea
                  className="
                    mt-1
                    block
                    w-full
                    rounded-md
                    bg-gray-100
                    border-transparent
                    focus:border-gray-500 focus:bg-white focus:ring-0
                  "
                  rows={3}
                  {...register("info")}
                />
              </label>
              <label className="flex justify-center items-center">
                <input
                  type="submit"
                  className="
                    mt-1
                    block
                    w-full py-[4px]
                    cursor-pointer
                    rounded-md
                    bg-gray-300
                    border-transparent
                    focus:border-gray-500 focus:bg-white focus:ring-0
                  "
                />
              </label>
            </div>
          </form>
        </div>
      </div>
    </Modal>
  );
};
export default HomeModal;
跟 todoPage 一樣,加一下吧~
      ...
      <HomeModal
        isOpen={isOpen}
        closeModal={() => dispatch(closeModal())}
        register={register}
        onSubmit={onSubmit}
        handleSubmit={handleSubmit}
        reset={reset}
      />
      ...
       <AddButton onClick={() => dispatch(openModal())} />
思考許久,我打算用最近一次新增的 todo 當作釘選的目標,所以我們要來把最近一次新增 todo 給揪出來,目前新加入的 todo 都是從後面加,所以就抓最後一個項目,新增一個 state 讓 home 持有 :
...
 const [todo, setTodo] = useState(()=>list[list.length - 1]);
 ...
加上這一步就算完成。
...
 <div className="flex flex-col justify-center ml-[8px] px-[8px]  w-[800px] pr-[8px]">
            <div className="w-full flex">
              <div className="w-2/12 flex items-center justify-center bg-gray-200 rounded-l-xl">
                已釘選
              </div>
              <div className="bg-slate-50 w-full pl-[8px]">
                <h3 className="">{todo.title}</h3>
                <div className="text-sm">{todo.info}</div>
              </div>
            </div>
          </div>
          ...
最後的 HomePage :
import React from "react";
import { useState } from "react";
import AddButton from "../../features/AddButton";
import HomeModal from "./HomeModal";
import { useAppSelector, useAppDispatch } from "../../redux/hooks";
import {
  selectModalIsOpen,
  openModal,
  closeModal,
} from "../../redux/modalSlice/modalSlice";
import { selectList, addTodo } from "../../redux/todoSlice/todoSlice";
import { useForm } from "react-hook-form";
const HomePage: React.FC = () => {
  const dispatch = useAppDispatch();
  const isOpen = useAppSelector(selectModalIsOpen);
  const list = useAppSelector(selectList);
  const [todo, setTodo] = useState(()=>list[list.length - 1]);
  const {
    register,
    handleSubmit,
    watch,
    reset,
    formState: { errors },
  } = useForm();
  console.log("list", list, "isOpen", isOpen);
  const onSubmit = (data) => {
    // setList([...list, data]);
    dispatch(addTodo(data));
    if (isOpen) dispatch(closeModal());
    reset();
    console.log("list", list);
  };
  return (
    <>
      <HomeModal
        isOpen={isOpen}
        closeModal={() => dispatch(closeModal())}
        register={register}
        onSubmit={onSubmit}
        handleSubmit={handleSubmit}
        reset={reset}
      />
      <section className="max-w-[1200px] mx-auto my-0 pt-[40px]">
        <div className="flex items-center justify-between">
          <AddButton onClick={() => dispatch(openModal())} />
          <div className="flex flex-col justify-center ml-[8px] px-[8px]  w-[800px] pr-[8px]">
            <div className="w-full flex">
              <div className="w-2/12 flex items-center justify-center bg-gray-200 rounded-l-xl">
                已釘選
              </div>
              <div className="bg-slate-50 w-full pl-[8px]">
                <h3 className="">{todo.title}</h3>
                <div className="text-sm">{todo.info}</div>
              </div>
            </div>
          </div>
        </div>
        <div className="pt-[20px]">
          <ul className="flex justify-between">
            <li className="p-[8px] mr-[16px] h-[600px] w-[450px] bg-gray-300">
              鐵櫃
            </li>
            <li className="p-[8px] mr-[16px] h-[600px] w-[450px] bg-gray-300">
              書櫃
            </li>
            <li className="p-[8px] mr-[16px] h-[600px] w-[450px] bg-gray-300">
              桌子
            </li>
            <li className="p-[8px] h-[600px] w-[450px] bg-gray-300">冰箱</li>
          </ul>
        </div>
      </section>
    </>
  );
};
export default HomePage;
今天完成了 todo 釘選的部分,成就感很微妙,堅持到今天了呢,繼續再接再厲。