版本二
const register = async () => {};
const Card = ({ children, onRegister }) => {
  const [message, setMessage] = useState();
  return (
    <div>
      <div>卡片標題</div>
      {children}
      <button
        onClick={() =>
          onRegister({
            onSuccess: (member) => {
              setMessage("註冊成功");
            },
            onError: (message) => {
              setMessage(`註冊失敗: ${message}`);
            },
            onFinish: () => {
              setTimeout(() => setMessage(null), 3000);
            },
          })
        }
      >
        註冊
      </button>
      {message && <div className="message">{message}</div>}
    </div>
  );
};
const Page = () => {
  const handleRegister = ({ onSuccess, onError, onFinish }) => {
    register()
      .then((data) => {
        onSuccess(data.member);
      })
      .catch((err) => {
        onError(data.error.message);
      })
      .finally(onFinish);
  };
  return (
    <div>
      <Card onRegister={handleRegister}>卡片內容</Card>
    </div>
  );
};
版本二的 <Card> props 收到的是一個Promise function handleRegister,我們在Page層級透過  handleRegister ,綁定了 register() 的 Promise 流程,在 handleRegister 我們會帶入 3 個 callback function 給 register() 且指定要帶什麼參數、資料給對應的 callback 使用。
這 3 個 function
onSuccess()onError()onFinish()會對應在Promise不同階段時去執行。
Page 負責專注處理整個頁面的商業邏輯
Card 也就是我們專注在樣式的 UI,但我們又希望能根據 商業邏輯 的 成功 or 失敗,做些對應的 UI 互動。
我們在 <Card> 會使用 Props 裡面的 Callback (onRegister) ,並且在這個 Callback 裡面再帶入 3 個預期的 樣式-商業邏輯互動 的 Callback。
onRegister({
  onSuccess: (member) => {
    setMessage("註冊成功");
  },
  onError: (message) => {
    setMessage(`註冊失敗: ${message}`);
  },
  onFinish: () => {
     setTimeout(() => setMessage(null), 3000);
   },
})
在這樣子的回呼函式彼此調用, button 呼叫 callback  onRegister 再帶回 3 個 callback 給 handleRegister 略顯複雜。