iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0
SideProject30

30天製作與眾不同的TodoList吧!系列 第 21

添加修改功能 - 建立彈窗

  • 分享至 

  • xImage
  •  

接下來我們可以為 Todo 添加修改功能。
照慣例,我們需要先確認需求。
我希望當 user 進行編輯的時候,會彈出一個視窗,其中包含兩個欄位,標題 & 內容 & 2 個按鍵,用於關閉視窗 & 確認更新資料。
這時候我們可以先透過 createPortal 建立一個彈窗

import { createPortal } from "react-dom";

const Modal = ({ children, isVisible, close }) => {
  if (!isVisible) return null;

  return createPortal(
    <div className="fixed top-0 left-0 right-0 bottom-0 bg-black/70 flex justify-center items-center">
      <div className="w-1/2 min-w-[300px] bg-white p-5 rounded-[4px]">
        <div className="w-full text-center">
          {children}
          <button
            onClick={close}
            className=" bg-red-500 text-white py-1 px-2 rounded-md"
          >
            關閉
          </button>
        </div>
      </div>
    </div>,
    document.body
  );
};

這邊的document.body表示這個彈窗的生成位置,3 個參數分別表示其中的可編輯內文 / 彈窗是否顯示 / 關閉彈窗。

並且使用 custom hook 來包裝這個來包裝這個 modal 讓我們可以在任何地方使用這個功能。

const useModal = () => {
  const [isVisible, setIsVisible] = useState(false);

  const show = () => setIsVisible(true);
  const hide = () => setIsVisible(false);

  const RenderModal = ({ children }) => (
    <Modal isVisible={isVisible} close={hide}>
      {children}
    </Modal>
  );

  return {
    show,
    hide,
    RenderModal,
  };
};

這邊可以看到透過 useModal 的方式將整個流程包裝成一個 custom hook,其中包含了開啟/關閉彈窗的 Method,RenderModal 表示內文渲染所包含的元素。

接下來我們需要使用這個 custom hook 來完成我們的 update 功能。

首先我們先回到 todo 的畫面加上下面這段,新增一個按鍵。

{
  renderRecover && (
    <TodoBtn
      renderChildren={renderRecover}
      handleClick={(e) => {
        handleAction(e, todo, handleRecover);
      }}
      className={"bg-yellow-700"}
    />
  );
}

這邊我們和前面的按鍵一樣,把icon & 功能往上拋至父層。
然後透過調用useModal讓我們點擊按鍵的時候顯示彈窗。
這邊透過解構賦值的方式,從useModal回傳的value中取出show ...等功能。

const { show, RenderModal, hide } = useModal();

當按鍵被點擊的時候,顯示視窗。

  const handleEditBtnClick = (item) => {
    show();
  };

上一篇
修正各種method-2、custom hook
下一篇
添加修改功能 - 修改todo
系列文
30天製作與眾不同的TodoList吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言