[英]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.