如何解決Typescript對React Hooks中使用mobx時props的類型檢查


最外層組件傳入 mobx 中的 stores:

import { stores } from "@/stores";
import { Provider } from "mobx-react";
ReactDOM.render(
  <Provider {...stores}>
    <App />
  </Provider>,
  document.getElementById("app") as HTMLElement
);

中間組件 App:

import React from "react";
import "./app.scss";
import Cards from "@/floors/Cards";
const App = () => {
  return (
    <div className="welcome-container">
      <Cards />
    </div>
  );
};
export default App;

子組件:如何定義 store 的類型,由於 store 相當於 props 傳入的,如果定義了 props 類型,則父組件' '就會報錯,因為沒有傳入 TS 規定的 store 類型;

interface IWelcomeProps {
  appStore: GlobalStores["appStore"];
  myPlusStore: GlobalStores["myPlusStore"];
}

const Cards: React.FC<IWelcomeProps> = (props: IWelcomeProps) => {
  const { appStore, myPlusStore } = props;
};
export default inject("appStore", "myPlusStore")(observer(Cards));

解決方法:
一:父組件 Cards 有自己的 props 時:
讓 store 定義的 TS 類型 IWelcomeProps 繼承於 MyComponentProps,這樣 IWelcomeProps 有了所有的 props 類型,
但是子組件傳入的類型是不包含 props 的 MyComponentProps 類型;
然后在組件內部讓 props 在斷言成 IWelcomeProps
這樣傳入的 props 只是父組件真正的 props 類型;而內部組件的 props 被斷言成包含了 store 和父組件 props 的類型

interface MyComponentProps {
  name?: string;
}

interface IWelcomeProps extends MyComponentProps {
  appStore: GlobalStores["appStore"];
  myPlusStore: GlobalStores["myPlusStore"];
}

const Cards: React.FC<MyComponentProps> = (props: MyComponentProps) => {
  const _props = props as IWelcomeProps;
  const { appStore, myPlusStore } = _props;
};
export default inject("appStore", "myPlusStore")(observer(Cards));

二:父組件沒有 props 的時候

定義了 store 類型 IWelcomeProps,在傳入 props 的時候使用 Partial<>,將其改為可選屬性,然后在子組件中使用斷言再將其改為真正的 store 屬性,騙過 ts 檢查

import React, { useState, useEffect } from "react";
import { inject, observer } from "mobx-react";
import { GlobalStores } from "@/stores";

interface IWelcomeProps {
  appStore: GlobalStores["appStore"];
  myPlusStore: GlobalStores["myPlusStore"];
}

const Cards = (props: Partial<IWelcomeProps>) => {
  const _props = props as IWelcomeProps;
  const { appStore, myPlusStore } = _props;
  const [currList, setCurrList] = useState("he");

  return (
    <div className="welcome-container">
      <p>我的初始名字是:{appStore.initName}</p>
    </div>
  );
};
export default inject("appStore", "myPlusStore")(observer(Cards));

參考文章:https://zhuanlan.zhihu.com/p/33406998


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM