我目前正在设置一个侦听类型LOCATION_CHANGE
或LocationChangeAction
动作的史诗,这是每当路由器历史记录因路由器操作(例如push
或replace
(而更改时触发的操作。
import { LOCATION_CHANGE, LocationChangeAction } from 'connected-react-router';
import { isActionOf } from 'typesafe-actions';
const locationEpic: Epic = (action$) => action$.pipe(
filter(isActionOf(LocationChangeAction)),
tap((action) => {
// do the rest here
})
);
但是,执行上述操作会引发错误,添加typeof
似乎也无济于事。
'LocationChangeAction' only refers to a type, but is being used as a value here.
我可以通过使用typesafe-actions
知道正确的方法是什么 的isActionOf()
运算符?
指
参数包含索引 0 处具有无效元素的数组,它应该是来自"类型安全操作"的操作创建者实例
它可能会抛出该错误,因为ActionCreator
包含需要getType?: () => TType
的 ActionCreatorTypeMetadata:
type TypeConstant = string;
export interface ActionCreatorTypeMetadata<TType extends TypeConstant> {
getType?: () => TType;
}
动作创造者export type ActionCreator<T extends { type: string }> = ((
...args: any[]
) => T) &
ActionCreatorTypeMetadata<T['type']>;
但是,onLocationChanged
函数仅实现交集的第一部分(返回具有属性type
的对象的函数(。
export const LOCATION_CHANGE = '@@router/LOCATION_CHANGE'
export const onLocationChanged = (location, action, isFirstRendering = false) => ({
type: LOCATION_CHANGE,
payload: {
location,
action,
isFirstRendering,
}
})
该函数还必须包含属性getType
:
onLocationChanged.getType = () => `YOUR_TYPE`.
打字稿游乐场
对于那些正在使用typesafe-actions
的人,您将需要注册LOCATION_CHANGE
操作,
import { LOCATION_CHANGE, RouterActionType } from 'connected-react-router';
import { Location } from 'history';
import { createAction } from 'typesafe-actions';
namespace RouterActions {
export const onLocationChanged = createAction(
LOCATION_CHANGE,
(action) => (location: Location, routerAction: RouterActionType, isFirstRendering?: boolean) => action({
location,
action: routerAction,
isFirstRendering,
}),
);
}
export default RouterActions;
在你的史诗中,你可以简单地听LOCATION_CHANGE
动作,
const locationEpic: Epic = (action$) => action$.pipe(
filter(isActionOf(RouterActions.onLocationChanged)),
switchMap((epic) => {
// do the rest
}),
);
除了安德烈的出色回答之外,我想为我的问题提出另一种解决方案。
显式定义"假"操作以从连接的 react-router 镜像 History 操作方法(例如push
、replace
onLocationChanged
(的问题在于,当您需要调用/侦听史诗上的操作(例如 redux-observables(时,它将出现进一步的下游问题。
因此,处理此问题的更好方法是在主 RootAction 上为历史记录操作方法添加类型。例如,如果您希望将replace
操作添加为ReduxRootAction
的一部分,
import { CallHistoryMethodAction, connectRouter, RouterState } from 'connected-react-router';
import { LocationState, Path } from 'history';
const actions = {
userActions,
settingsActions
};
type Replace = (path: Path, state?: LocationState) => CallHistoryMethodAction<[Path, LocationState?]>;
interface RouteActions {
replace: Replace;
}
export type RootAction = ActionType<typeof actions> | ActionType<RouteActions>;
export interface RootState {
router: RouterState;
user: UserState;
settings: SettingsState;
}
这将防止TypeScript
/typesafe-actions
标记未定义历史记录操作的错误。