![](/img/trans.png)
[英]How can I use optional chaining in object data when I use JavaScript?
[英]How can I avoid optional chaining in Typescript?
我試圖在 redux 中存儲名為Targetfarms
的 object 數據。我為Targetfarms
分配了一個名為Farmstype
的類型。
但是,當我在MainPage
組件中使用帶有Targetfarms
的useSelector
並且我想使用targetfarm.aircon
時,如果我不在Targetfarms
中使用可選鏈接,則會發生此錯誤。
Targetfarms is possibly null,
如果我使用optional chaining,我可以正常獲取Targetfarms
數據,但我不想盡可能使用optional chaining。
我該如何修復我的代碼?
這是我的代碼:
export interface Farmstype {
aircon: aircontype;
children: Farmstype[];
equips: euiptype[];
latitude: number;
longitude: number;
modDate: string;
name: string;
placeId: number;
placeInfo: placeInfotype;
productCode: string;
productCodeInfo: productCodeInfotypes;
productLifeCycles: productLifeCyclestype[];
roadNameAddress: string;
stnIds: number;
type: string;
}
interface InitialState {
Targetfarms: Farmstype | null;
}
const initialState: InitialState = {
Targetfarms: null,
};
const postSlice = createSlice({
name: "post",
initialState,
reducers: {
// targetLoadFarm
targetFarm(state, action: PayloadAction<Farmstype>) {
state.Targetfarms = action.payload;
},
}
主頁
const MainPage = () => {
const { Targetfarms} = useSelector((state: RootState) => state.post);
console.log("Targetfarms:", Targetfarms?.placeId); // Targetfarms is possibly null,
}
擺脫當前設置的可選鏈接的一個想法是靜態鍵入世界的 state 並編寫不同的組件。
不確定我是否正確構建了您的商店,但您明白了。
type RootState = {
app: 'init' | 'running' // we model the state of the app
post: {
Targetfarms: Farmstype | null
}
}
// We dispatch to the correct implementation depending on the state of the world
const MainPage = () =>
useSelector({ app }: RootState) => app) === 'running'
? RunningPage()
: InitPage();
const RunningPage = () => {
const { Targetfarms } = useSelector((state: RunningState) => state.post);
// OK
const f = Targetfarms.placeId
}
const InitPage = () => {
const { Targetfarms } = useSelector((state: InitState) => state.post);
// @ts-expect-error: Targetfarms is possibly null
const f = Targetfarms.placeId
}
有許多方法可以產生不同的狀態。 這是一個選項。
// When the app is 'running' `post/Targetfarms` is unlocked
type RunningState = Unlock<RootState, ['post', 'Targetfarms']> & {
state: 'running'
};
// Otherwise Targetfarms is still nullable
type InitState = RootState & {
state: 'init'
};
type Unlock<State, Path extends PropertyKey[]> = unknown & {
[K in keyof State]: Path['length'] extends 1
? K extends Path[0] ? NonNullable<State[K]> : State[K]
: Unlock<
State[K],
Path extends [PropertyKey, ...infer U] ? U & PropertyKey[] : never
>
}
如果您的app
狀態很少,而 state 有很多可為 null 的部分,那么此解決方案可能會開始變得有趣。基本上,您可以在根目錄中一次性決定應用程序在 state 中的位置,而不是多次在需要值的位置。
也許您正在嘗試訪問 object 的屬性,該屬性在初始化之前可能是 null 或未定義。 為避免此錯誤,您有以下幾種選擇:
在嘗試訪問其屬性之前,您可以檢查 object 是 null 還是未定義。 例如:
if (Targetfarms) {
console.log(Targetfarms.placeId);
}
您可以使用 || 為 Targetfarms 設置默認值操作員。 例如:
const {Targetfarms} = useSelector((state: RootState) => state.post) || {};
console.log(Targetfarms.placeId);
這會將 Targetfarms 的默認值設置為空 object,這意味着您可以訪問其屬性而不會出現錯誤。
注意:我認為並且這只是我的意見,可選鏈接是避免 null 或未定義的好方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.