首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带类型操作和连接反应路由器的epics的使用

带类型操作和连接反应路由器的epics的使用
EN

Stack Overflow用户
提问于 2019-12-20 11:24:38
回答 2查看 1K关注 0票数 1

我目前正在设置一个epic,它侦听LOCATION_CHANGELocationChangeAction类型的操作,这是在路由器历史因路由器操作(如pushreplace )而发生更改时触发的操作。

代码语言:javascript
复制
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似乎也没有帮助。

代码语言:javascript
复制
'LocationChangeAction' only refers to a type, but is being used as a value here.

通过使用typesafe-actionsisActionOf()操作符,我可以知道正确的方法是什么吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-21 06:40:07

参数包含在索引0处具有无效元素的数组,它应该是“typesafe-action”中的动作创建者实例。

它可能会引发该错误,因为ActionCreator包含需要getType?: () => TTypeActionCreatorTypeMetadata

代码语言:javascript
复制
type TypeConstant = string;

export interface ActionCreatorTypeMetadata<TType extends TypeConstant> {
  getType?: () => TType;
}

ActionCreator

代码语言:javascript
复制
export type ActionCreator<T extends { type: string }> = ((
  ...args: any[]
) => T) &
  ActionCreatorTypeMetadata<T['type']>;

但是,onLocationChanged函数只实现了交集的第一部分(返回具有属性type的对象的函数)。

代码语言:javascript
复制
export const LOCATION_CHANGE = '@@router/LOCATION_CHANGE'

export const onLocationChanged = (location, action, isFirstRendering = false) => ({
  type: LOCATION_CHANGE,
  payload: {
    location,
    action,
    isFirstRendering,
  }
})

该函数还必须包含属性getType

代码语言:javascript
复制
onLocationChanged.getType = () => `YOUR_TYPE`.

TypeScript游乐场

对于那些使用typesafe-actions的用户,您需要注册LOCATION_CHANGE操作,

代码语言:javascript
复制
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的动作,

代码语言:javascript
复制
const locationEpic: Epic = (action$) => action$.pipe(
  filter(isActionOf(RouterActions.onLocationChanged)),
  switchMap((epic) => {
    // do the rest
  }),

);
票数 3
EN

Stack Overflow用户

发布于 2020-03-19 03:47:33

除了安德烈出色的回答之外,我还想为我的问题提出另一种解决办法。

显式定义“假”操作以反映来自连接反应路由器 (例如pushreplaceonLocationChanged)的历史操作方法的问题是,当您需要调用/侦听史诗上的操作(如redux-可观测)时,它将进一步处理下游问题。

因此,处理此问题的更好方法是在主RootAction上添加历史操作方法的类型。例如,如果希望将replace操作添加为Redux RootAction的一部分,

代码语言:javascript
复制
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标记未定义历史操作的错误。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59424518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档