使用 UseReducer 和 useContext 挂钩进行调度:类型 {} 上不存在调度
dispatch with UseReducer and useContext hooks: dispatch does not exist on type {}
我正在尝试使用 React 构建一个小型 Cesium 应用程序,它可以通过单击与每个位置相关联的按钮缩放到地球上的各个地方。我正在使用 useContext 和 useReducer 挂钩设置减速器,但我遇到了一个我无法弄清楚的调度问题,到目前为止还没有找到任何指向我的问题的东西可能。到目前为止,我看过的所有页面都告诉我,我所拥有的应该可以工作,但我显然遗漏了一些东西。
下面是我正在使用的两个文件:
位置-card.tsx
export function LocationCard(props: LocationCardProps) {
const classes = useStyles();
const { className, name, type, location, onDetails } = props;
const { dispatch } = useMapViewerContext();
return (
<Card variant="outlined" className={classes.locationCard}>
<div className={classes.locationDetails}>
<CardContent className={classes.locationContent}>
<Typography component="div" variant="subtitle2">
{name}
</Typography>
<Typography variant="caption" color="textSecondary">
{type}
</Typography>
</CardContent>
<div className={classes.locationCardControls}>
<Tooltip title="Zoom to Location">
<IconButton
aria-label="Zoom To Location"
onClick={() => {dispatch(zoomToLocation(location))}}
className={classes.locationButton}
>
.....
上述文件还有更多内容,但这是相关的部分。我得到的错误是我尝试设置调度的地方。有人告诉我
Property 'dispatch' does not exist on type '{}'
地图查看器-context.tsx
import React, { useContext, useReducer, useState } from 'react';
import Cartesian3 from 'cesium/Source/Core/Cartesian3';
import { Context } from 'node:vm';
export interface MapViewerState {
location: Cartesian3;
isCameraFlyTo: boolean;
zoomToLocation: (value: Cartesian3) => void;
}
const initialState: MapViewerState = {
location: Cartesian3.fromDegrees(
-95.96044633079181,
41.139682398924556,
2100
),
isCameraFlyTo: false,
zoomToLocation: undefined,
};
export const MapViewerContext = React.createContext();
// Actions
export const ZOOM_TO_LOCATION = "ZOOM_TO_LOCATION";
export const COMPLETE_ZOOM = "FINISH";
// Action creators
export const zoomToLocation = (value: Cartesian3) => {
return { type: ZOOM_TO_LOCATION, value };
}
// Reducer
export const mapViewerReducer = (state, action): MapViewerState => {
switch (action.type) {
case ZOOM_TO_LOCATION:
return {...state, location: action.value, isCameraFlyTo: true};
case COMPLETE_ZOOM:
return {...state, isCameraFlyTo: false}
default:
return state;
}
}
const MapViewerProvider = (props) => {
const [state, dispatch] = useReducer(mapViewerReducer, initialState);
const mapViewerData = { state, dispatch };
return <MapViewerContext.Provider value={mapViewerData} {...props} />;
};
const useMapViewerContext = () => {
return useContext(MapViewerContext);
};
export { MapViewerProvider, useMapViewerContext };
这里是我设置动作、reducer 和上下文的地方。我也有一个问题 React.createContext() 没有争论。我可以通过为它提供我定义的 initialState 来消除该错误,但是 location-card.tsx 中的错误只是改变了至:
Property 'dispatch' does not exist on type 'MapViewerState'.
谁能帮我弄清楚如何让它工作?到目前为止我尝试过的一切都失败了。
您看到的错误是由于 createContext
没有正确推断您的上下文类型造成的。您可以像这样明确指定上下文的类型:
export interface MVContext {
state: MapViewerState;
dispatch: (action: MapViewerAction) => void;
}
export const MapViewerContext = createContext<MVContext>({} as MVContext);
只要您不打算在上下文提供程序之外使用 useContext
,类型强制 {} as MVContext
就是安全的。如果是,则需要为每个键提供默认值:
export const MapViewerContext = createContext<MVContext>({
state: MapViewerState.Default,
dispatch: () => {},
});
您为 map-view-context
编写的代码很有趣。我把它提取出来供我通读。
1 export const MapViewerContext = React.createContext();
2 const MapViewerProvider = (props) => {
3 const [state, dispatch] = useReducer(mapViewerReducer, initialState);
4 const mapViewerData = { state, dispatch };
5 return <MapViewerContext.Provider value={mapViewerData} {...props} />;
6 };
7 const useMapViewerContext = () => {
8 return useContext(MapViewerContext);
9 };
10export { MapViewerProvider, useMapViewerContext };
我假设您的代码用法如下。
<MapViewerProvider>
<Children />
</MapViewerProvider>
const Children = () => {
const { state, dispatch } = useMapViewerContext()
}
你可以这样试试吗
<MapViewerContext.Provider value={useReducer(..., ...)}>
<Children />
<MapViewerContext.Provider />
const Children = () => {
const [ state, dispatch ] = useContext(MapViewerContexxt)
}
我知道这和你做的很相似。我将 {}
更改为 []
而没有添加另一个临时变量。因为我的直觉是这条线,LINE 4.
const mapViewerData = { state, dispatch };
每次进入此渲染时,您都会以某种方式获得 value
的新实例。
我正在尝试使用 React 构建一个小型 Cesium 应用程序,它可以通过单击与每个位置相关联的按钮缩放到地球上的各个地方。我正在使用 useContext 和 useReducer 挂钩设置减速器,但我遇到了一个我无法弄清楚的调度问题,到目前为止还没有找到任何指向我的问题的东西可能。到目前为止,我看过的所有页面都告诉我,我所拥有的应该可以工作,但我显然遗漏了一些东西。
下面是我正在使用的两个文件:
位置-card.tsx
export function LocationCard(props: LocationCardProps) {
const classes = useStyles();
const { className, name, type, location, onDetails } = props;
const { dispatch } = useMapViewerContext();
return (
<Card variant="outlined" className={classes.locationCard}>
<div className={classes.locationDetails}>
<CardContent className={classes.locationContent}>
<Typography component="div" variant="subtitle2">
{name}
</Typography>
<Typography variant="caption" color="textSecondary">
{type}
</Typography>
</CardContent>
<div className={classes.locationCardControls}>
<Tooltip title="Zoom to Location">
<IconButton
aria-label="Zoom To Location"
onClick={() => {dispatch(zoomToLocation(location))}}
className={classes.locationButton}
>
.....
上述文件还有更多内容,但这是相关的部分。我得到的错误是我尝试设置调度的地方。有人告诉我
Property 'dispatch' does not exist on type '{}'
地图查看器-context.tsx
import React, { useContext, useReducer, useState } from 'react';
import Cartesian3 from 'cesium/Source/Core/Cartesian3';
import { Context } from 'node:vm';
export interface MapViewerState {
location: Cartesian3;
isCameraFlyTo: boolean;
zoomToLocation: (value: Cartesian3) => void;
}
const initialState: MapViewerState = {
location: Cartesian3.fromDegrees(
-95.96044633079181,
41.139682398924556,
2100
),
isCameraFlyTo: false,
zoomToLocation: undefined,
};
export const MapViewerContext = React.createContext();
// Actions
export const ZOOM_TO_LOCATION = "ZOOM_TO_LOCATION";
export const COMPLETE_ZOOM = "FINISH";
// Action creators
export const zoomToLocation = (value: Cartesian3) => {
return { type: ZOOM_TO_LOCATION, value };
}
// Reducer
export const mapViewerReducer = (state, action): MapViewerState => {
switch (action.type) {
case ZOOM_TO_LOCATION:
return {...state, location: action.value, isCameraFlyTo: true};
case COMPLETE_ZOOM:
return {...state, isCameraFlyTo: false}
default:
return state;
}
}
const MapViewerProvider = (props) => {
const [state, dispatch] = useReducer(mapViewerReducer, initialState);
const mapViewerData = { state, dispatch };
return <MapViewerContext.Provider value={mapViewerData} {...props} />;
};
const useMapViewerContext = () => {
return useContext(MapViewerContext);
};
export { MapViewerProvider, useMapViewerContext };
这里是我设置动作、reducer 和上下文的地方。我也有一个问题 React.createContext() 没有争论。我可以通过为它提供我定义的 initialState 来消除该错误,但是 location-card.tsx 中的错误只是改变了至:
Property 'dispatch' does not exist on type 'MapViewerState'.
谁能帮我弄清楚如何让它工作?到目前为止我尝试过的一切都失败了。
您看到的错误是由于 createContext
没有正确推断您的上下文类型造成的。您可以像这样明确指定上下文的类型:
export interface MVContext {
state: MapViewerState;
dispatch: (action: MapViewerAction) => void;
}
export const MapViewerContext = createContext<MVContext>({} as MVContext);
只要您不打算在上下文提供程序之外使用 useContext
,类型强制 {} as MVContext
就是安全的。如果是,则需要为每个键提供默认值:
export const MapViewerContext = createContext<MVContext>({
state: MapViewerState.Default,
dispatch: () => {},
});
您为 map-view-context
编写的代码很有趣。我把它提取出来供我通读。
1 export const MapViewerContext = React.createContext();
2 const MapViewerProvider = (props) => {
3 const [state, dispatch] = useReducer(mapViewerReducer, initialState);
4 const mapViewerData = { state, dispatch };
5 return <MapViewerContext.Provider value={mapViewerData} {...props} />;
6 };
7 const useMapViewerContext = () => {
8 return useContext(MapViewerContext);
9 };
10export { MapViewerProvider, useMapViewerContext };
我假设您的代码用法如下。
<MapViewerProvider>
<Children />
</MapViewerProvider>
const Children = () => {
const { state, dispatch } = useMapViewerContext()
}
你可以这样试试吗
<MapViewerContext.Provider value={useReducer(..., ...)}>
<Children />
<MapViewerContext.Provider />
const Children = () => {
const [ state, dispatch ] = useContext(MapViewerContexxt)
}
我知道这和你做的很相似。我将 {}
更改为 []
而没有添加另一个临时变量。因为我的直觉是这条线,LINE 4.
const mapViewerData = { state, dispatch };
每次进入此渲染时,您都会以某种方式获得 value
的新实例。