首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

尝试实现动作缩减程序时出现angular ngrx抛出错误

在Angular中使用NgRx进行状态管理时,如果遇到错误,通常是由于状态管理的不当使用或代码中的逻辑错误导致的。以下是一些常见的错误及其解决方案:

常见错误及原因

  1. 状态不可变性问题
    • 原因:NgRx要求状态的更新必须是不可变的,即不能直接修改现有的状态对象。
    • 错误信息:可能会看到类似于“Cannot assign to read only property”的错误。
  • 选择器(Selectors)使用不当
    • 原因:选择器可能没有正确地从状态树中提取数据,或者在选择器中进行了不恰当的计算。
    • 错误信息:可能会看到“undefined”或其他类型错误。
  • 动作(Actions)和缩减器(Reducers)不匹配
    • 原因:发送的动作类型可能与缩减器中定义的不匹配,导致状态更新失败。
    • 错误信息:可能会看到“Action not found”或类似的错误。
  • Effect中的副作用处理不当
    • 原因:Effect可能没有正确处理异步操作,或者在Effect中进行了不恰当的状态修改。
    • 错误信息:可能会看到网络请求相关的错误或状态未更新的错误。

解决方案

1. 确保状态更新是不可变的

使用immer库可以帮助你以更简洁的方式进行不可变更新:

代码语言:txt
复制
import produce from 'immer';

const initialState = { count: 0 };

function reducer(state = initialState, action: Action) {
  switch (action.type) {
    case 'INCREMENT':
      return produce(state, draft => {
        draft.count++;
      });
    default:
      return state;
  }
}

2. 正确使用选择器

确保选择器能够正确地从状态树中提取数据:

代码语言:txt
复制
import { createSelector } from '@ngrx/store';

export const selectFeature = (state: AppState) => state.feature;

export const selectCount = createSelector(
  selectFeature,
  (state: FeatureState) => state.count
);

3. 确保动作和缩减器匹配

检查动作类型是否在缩减器中正确处理:

代码语言:txt
复制
// actions.ts
export const increment = createAction('[Counter] Increment');

// reducer.ts
function reducer(state = initialState, action: Action) {
  switch (action.type) {
    case '[Counter] Increment':
      return { ...state, count: state.count + 1 };
    default:
      return state;
  }
}

4. 正确处理Effect中的副作用

确保Effect能够正确处理异步操作,并且不直接修改状态:

代码语言:txt
复制
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { SomeService } from './some.service';
import { fetchDataSuccess, fetchDataFailure } from './actions';

@Injectable()
export class DataEffects {
  constructor(
    private actions$: Actions,
    private someService: SomeService
  ) {}

  fetchData$ = createEffect(() =>
    this.actions$.pipe(
      ofType('[Data] Fetch Data'),
      mergeMap(() =>
        this.someService.getData().pipe(
          map(data => fetchDataSuccess({ data })),
          catchError(error => of(fetchDataFailure({ error })))
        )
      )
    )
  );
}

示例代码

假设我们有一个简单的计数器应用,使用NgRx进行状态管理:

代码语言:txt
复制
// counter.reducer.ts
import { createReducer, on } from '@ngrx/store';

export const initialState = { count: 0 };

const _counterReducer = createReducer(
  initialState,
  on(increment, state => ({ ...state, count: state.count + 1 })),
  on(decrement, state => ({ ...state, count: state.count - 1 }))
);

export function counterReducer(state, action) {
  return _counterReducer(state, action);
}

// counter.actions.ts
import { createAction } from '@ngrx/store';

export const increment = createAction('[Counter] Increment');
export const decrement = createAction('[Counter] Decrement');

// counter.effects.ts
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { SomeService } from './some.service';
import { incrementSuccess, incrementFailure } from './actions';

@Injectable()
export class CounterEffects {
  constructor(
    private actions$: Actions,
    private someService: SomeService
  ) {}

  incrementData$ = createEffect(() =>
    this.actions$.pipe(
      ofType('[Counter] Increment'),
      mergeMap(() =>
        this.someService.increment().pipe(
          map(() => incrementSuccess()),
          catchError(error => of(incrementFailure({ error })))
        )
      )
    )
  );
}

通过以上步骤和示例代码,你应该能够解决在使用NgRx时遇到的一些常见问题。如果问题仍然存在,请提供具体的错误信息和代码片段,以便进一步诊断。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

一个Angular 5教程:一步一步指导实现你的第一个Angular 5应用程序

现在,让我们尝试了解它在做什么,并使用传递的参数selector来生成我们的组件声明。这只是为我们做了很多样板工作,并以工作形式回馈我们的组件声明。我们不必实现额外的代码来支持任何装饰器的参数。...如果您是从头开始创建一个新组件,并忘记向NgModule添加一个新模块,但尝试将其添加到您的标记中,那么您的应用程序将无法使用JS控制台中的下一个错误: Uncaught Error: Template...State是一个单一的,不可变的数据结构 - 至少Ngrx为我们实现它的方式。Ngrx是由Redux提供灵感的“RxJS支持Angular应用程序的状态管理库”。 Ngrx的灵感来自Redux。...正如我们从它的实现中可以看到的那样,它也将我们的ServerFailure动作映射到它的有效负载,然后显示这个有效负载(我们的服务器错误)console.log。...如果您想采取更先进的措施,请尝试使用Angular 4 Forms:由Toptaler Igor Geshoki进行嵌套和输入验证。 理解基础知识 我们为什么要使用Angular?

42.7K10

Angular vs React 最全面深入对比

选择的方法 在选择之前,我们尝试带着一些问题去审视你将要选择的框架(或者是任何工具),尝试用这些问题的答案来帮助我们更加了解框架,也更加让选择变得更容易 框架本身的问题: 是否成熟?谁在背后支持呢?...如果在JSX标记中发生错误,编译器会立即报错而不是留待运行时出现莫名其妙的问题。这有助于开发人员快速排查错误以及避免其它愚蠢的错误,比如拼写错误。...Reducers本身是纯功能,与组件分开实现。这样可以更好地分离问题和测试。 如果你正在开展一个简单的项目,那么引入Redux可能有点得不偿失,但对于中等和大型项目来说,这是一个很好的选择。...@ngrx/store @ngrx/store是由Redux启发的Angular的状态管理库,基于由pure reducer进行突变的状态。...如果您正在开展一个大型项目,并希望尽可能减少错误选择的风险,请考虑先创建一个demo用于验证产品概念。选择项目的一些主要功能,并尝试使用其中一个框架以简单的方式实现它们。

3.8K70
  • 写在 2021: 值得关注学习的前端框架和工具库

    但有一点请注意,学有余力不是因为当前方向浅尝辄止而学有余力,是在当前方向足够深入同时还学有余力~对于不知道学啥的同学,就有了这篇文章,我会在接下来罗列我深入/尝试/了解过的,认为值得学习的各个方向框架与工具类库...Ionic[20],出现比较早的一个跨端方案,最开始只支持Angular,现在还支持了React和Vue,暂时没有使用过。目前的了解是性能与Vue支持上存在一些问题(所以Angular YES)。...NgRx[93],很好用的Angular的状态管理方案,写法和Redux非常像,也是action >>> reducer >>> state,所以几乎可以没有什么成本的上手。...秉承了Angular的思想,提供了一整套的集成:和Angular Router的集成:@ngrx/router-store;对于集合类型的适配:@ngrx/entity;副作用管理:@ngrx/effects...以上就是我 关注/接触/尝试/深度使用 过的大部分框架与工具库了,如果你恰好学有余力又不知道该学啥,不妨就从这里找找感兴趣的,最后再打个广告,我所在的组(阿里巴巴-淘系技术部-前端架构)正在招2022级的前端实习生

    4.2K10

    在同一基准下对前端框架进行比较

    通常“todo”并没有传达出在构建真正的程序时所需的足够的知识和视角,。 标准化 一个符合某些规则的项目。提供后端API、静态标记、样式和规范。...唯一要求是它是否出现在了 RealWorld 的代码仓库页面上。 ? 我们关注那些指标? 表现 此程序需要多长时间才能显示内容并变得可用? 大小 应用有多大?...如果说调试是删除软件错误的过程,那么编程必须是把它们加进去的过程  — Edsger Dijkstra 简述 这显示了给定库、框架或语言的简洁程度。...注意 Angular + ngrx:在 /libs 文件夹内完成的代码行数计算,仅包括*.ts 和 *.html 文件。如果你觉得这是错的,请告诉我正确的值是多少,以及你是如何计算的。...注意 Hyperapp:文章发布时代码行数不正确,感谢 Mateusz Kwasniewski 指出错误并提供了正确计算方法。

    96020

    同样做前端,为何差距越来越大?

    由于历史原因,开发框架同时基于 React 和 Angular,考虑到产品的复杂性、人员的短缺和技术背景各异,我们尝试了各种方法打磨工具体系来提升开发效率,以下分享五点。 ?...我们先后尝试过原生 Redux、分形 Fractal 的思路、自研类 Mobx 框架、Angular Service,最终认为 Redux 依旧是复杂应用数据流处理最佳选项之一。...庆幸的是除了 React 社区,Vue 社区有类似的 Vuex,Angular 社区有 NgRx 也提供了几乎同样的能力,甚至 NgRx 还可以无缝使用 redux-devtools 来调试状态变化。...曾经 React 和 Angular 是两个很难调和的框架,开发中浪费了我们大量的人力。...通过 CR 让项目中任何一行代码都至少被两人触达过,减少了绝大多数的低级错误,提升了代码质量,这也是帮助新人成长最快的方式之一。 ?

    1.2K20

    写在2021: 值得关注学习的前端框架和工具库

    但有一点请注意,学有余力不是因为当前方向浅尝辄止而学有余力,是在当前方向足够深入同时还学有余力~ 对于不知道学啥的同学,就有了这篇文章,我会在接下来罗列我深入/尝试/了解过的,认为值得学习的各个方向框架与工具类库...Ionic,出现比较早的一个跨端方案,最开始只支持Angular,现在还支持了React和Vue,暂时没有使用过。目前的了解是性能与Vue支持上存在一些问题(所以Angular YES)。...NgRx,很好用的Angular的状态管理方案,写法和Redux非常像,也是action >>> reducer >>> state,所以几乎可以没有什么成本的上手。...秉承了Angular的思想,提供了一整套的集成:和Angular Router的集成:@ngrx/router-store;对于集合类型的适配:@ngrx/entity;副作用管理:@ngrx/effects...以上就是我 关注/接触/尝试/深度使用 过的大部分框架与工具库了,如果你恰好学有余力又不知道该学啥,不妨就从这里找找感兴趣的

    2.9K10

    给2019前端开发的你5个进阶建议~

    由于历史原因,开发框架同时基于 React 和 Angular,考虑到产品的复杂性、人员的短缺和技术背景各异,我们尝试了各种方法打磨工具体系来提升开发效率,以下是节选的5项主要方法。...我们先后尝试过原生 Redux、分形 Fractal 的思路、自研类 Mobx 框架、Angular Service,最终认为 Redux 依旧是复杂应用数据流处理最佳选项之一。...庆幸的是除了 React 社区,Vue 社区有类似的 Vuex,Angular 社区有 NgRx 也提供了几乎同样的能力,甚至 NgRx 还可以无缝使用 redux-devtools 来调试状态变化。...曾经 React 和 Angular 是两个很难调和的框架,开发中浪费了我们大量的人力。...通过 CR 让项目中任何一行代码都至少被两人触达过,减少了绝大多数的低级错误,提升了代码质量,这也是帮助新人成长最快的方式之一。 ?

    1K10

    2018 前端趋势:更一致,更简单

    在我看来,还没有哪一个框架已经同时实现即好开发,又好使用。...这可以通过使用像 service workers 来实现离线支持和应用程序清单文件来定制应用在操作系统中的外观等新技术来实现。这可以被看作是响应式网页设计的自然演变。...无需猜测错误发生的原因,或者要求用户截图以及日志转储,LogRocket 可以让你重现会话以便快速了解发生了什么错误。...无需考虑框架,它适用于任何应用程序,也有插件可以从 Redux、Vuex和@ngrx/tore 上记录额外的上下文。...除了记录 Redux 动作和状态之外,LogRocket 还会记录控制台日志、JavaScript 错误、堆栈信息、带有头+主体的网络请求/响应、浏览器元数据和自定义日志。

    1.4K20

    8分钟为你详解React、Angular、Vue三大框架

    数据动作是一个对象,其职责是描述已经发生的事情:例如,一个数据动作描述的是一个用户 "follow"另一个用户。...存储仓库,是一个数据模型,可以根据从调度器接收到的数据动作来改变自己。 这种模式有时被表述为 "属性向下流动,数据动作向上流动"。...自Flux诞生以来,Flux的许多实现被创造出来,其中最著名的是Redux,它的特点是单一的存储仓库,通常被称为单一的数据真相源。...RxJS限制了状态的可见性和调试,但这些问题可以通过像ngReact或ngrx这样的反应式附加组件来解决。 支持Angular Universal,可以在服务器上运行Angular应用程序。...当在变换组件中的元素被插入或移除时,会出现这样的情况: Vue会自动检测到目标元素是否应用了CSS变换或动画。如果有,CSS变换类将在适当的时间添加/删除。

    22.2K20

    发那科报警代码

    006 符号“-”使用错误(不允许负值的地址后面出现“-”,或者出现两个连续的“-”)。 007 小数点“.” 使用不正确。 009 字符出现在无法使用该字符的位置。...014 程序中出现同步进给指令(本机无此功能)。 015 尝试同时移动四个轴。 020 在圆弧插补中,CNC专业微信号cncdar,起点和终点到圆心的差值大于参数876指定的值。...033 编程了刀具半径补偿中不能出现的交点。 034 圆弧插补出现在刀具半径补偿的开始或取消程序段处。 037 尝试用G17、G18或G19改变刀具半径补偿方式下的平面选择。...073 输入新程序时尝试使用现有程序编号。 074 程序编号不是 1 到 9999 之间的整数。 076 子程序调用指令M98中没有地址P。 077 子程序嵌套超过三层。...第437章 Z轴电机参数错误。检查参数 No.8320、8322、8323 和 8324。 3、超程报警报警号 报警内容: 510 X轴正向软限位超程。 511 X轴负软限位超程。

    23310

    前端架构101:MVC的不足与Flux的崛起

    这也和上一条「不可预测」相对应 响应顺序:如果存在多个对象响应同一个事件的话,有时候对响应的顺序是有要求的,某些变更不可以出现在其他的变更之前 有条件响应:对于传播方而言,并非希望所有的时间都一视同仁的广播出去...包括但不限于:Redux,Mobx,Ngrx,Akita,React 等等。...而在他们的项目中最大的阻碍竟然是 MVC 架构 整个宣讲 Flux 过程中最令人诟病的就是这一张图,在我上面提到的批评声音中,最共同的声音就是它们以一种错误的方式实施了 MVC,所以才导致了他们的应用无法拓展...所以你现在理解了为什么 Flux 会尝试用单向数据流解决这个问题了。...如果你开发的是 Angular 应用,Angular 本身,或是 Rxjs 又或是 TypeScript 哪一个单拎出来都不好对付,指望着人们自我学习或者培训的方式统一大家的水平更是天方夜谭。

    1.4K20

    PHP 使用协同程序实现合作多任务(二)

    调高并发数(比如 -c 500),服务器大多数运行良好,不过某些连接将抛出“连接被对方重置”的错误。由于我对低级别的socket资料了解的非常少,所以 我不能指出问题出在哪儿。...正如在这篇文章的开始 所提到的,调用生成器(或者协程)将没有真正地做任何事情,它仅仅返回一个对象。这也出现在上面的例子里。echoTimes调用除了放回一个(无用的)协程对象外不做任何事情。...不过,我仍然了一讲一下常见的协程错误处理:协程允许使用 throw() 方法在其内部抛出一个错误。尽管此方法还未在 PHP 中实现,但我很快就会提交它,就在今天。...throw() 方法接受一个 Exception,并将其抛出到协程的当前悬挂点,看看下面代码: ? 实现了它。同时我发现协程真正令人心慌。

    56410

    协程中的取消和异常 | 异常处理详解

    开发者们通常会在打磨应用的正常功能上花费很多时间,但是当应用出现一些意外情况时,给用户提供合适的体验也同样重要。...如果您不希望这种事情发生,可以尝试在创建协程时在 CoroutineScope 的 CoroutineContext 中使用 Job 的另一个扩展: SupervisorJob。...如果您想要在出现错误时不会退出父级和其他平级的协程,那就使用 SupervisorJob 或 supervisorScope。...工作原理 如果您对 Job 的底层实现感到疑惑,可以查看 JobSupport.kt 文件中对 childCancelled 和 notifyCancelling 方法的扩展。...内部协程会在异常出现时传播异常并传递给它的父级,由于父级并不知道 handler 的存在,异常就没有被抛出。 优雅地处理程序中的异常是提供良好用户体验的关键,在事情不如预期般发展时尤其如此。

    1.1K20

    Python面向对象编程-自定义异常使用(一)

    定义文件时,当文件的格式不正确时,我们可以抛出自定义异常来指示错误。在编写网络应用程序时,如果网络请求失败,我们可以抛出自定义异常来指示错误。...在编写数据库应用程序时,如果数据库连接失败,我们可以抛出自定义异常来指示错误。在编写游戏时,如果玩家尝试在不允许的情况下执行某个操作,我们可以抛出自定义异常来指示错误。...下面是一个使用自定义异常的示例,它演示了如何在游戏中处理玩家错误操作:class InvalidMoveError(Exception): def __init__(self, message):...在 make_move 方法中,如果玩家选择了无效的行或列,则抛出 InvalidMoveError。如果玩家选择了已经被占用的方格,则也会抛出 InvalidMoveError。...在 while 循环中,我们不断调用 make_move 方法,并在出现异常时捕获和处理异常。在异常处理程序中,我们将打印错误消息,告诉用户出现了什么错误。

    29141

    破解 Kotlin 协程(4) - 异常处理篇

    ,出现未捕获的异常会尝试传递给父协程并尝试取消父协程。...这一块儿稍微显得有点儿复杂,但仔细理一下主要有三条线: 协程内部异常处理流程:launch 会在内部出现未捕获的异常时尝试触发对父协程的取消,能否取消要看作用域的定义,如果取消成功,那么异常传递给父协程...上)的 CoroutineExceptionHandler 进行处理,如果仍然没有,那么就将异常交给当前线程的 UncaughtExceptionHandler 处理;而 async 则在未捕获的异常出现时同样会尝试取消父协程...join 和 await 的不同:join 只关心协程是否执行完,await 则关心运行的结果,因此 join 在协程出现异常时也不会抛出该异常,而 await 则会;考虑到作用域的问题,如果协程抛异常...,可能会导致父协程的取消,因此调用 join 时尽管不会对协程本身的异常进行抛出,但如果 join 调用所在的协程被取消,那么它会抛出取消异常,这一点需要留意。

    1.3K10

    禁止在代码中使用异常,一次时隔7年的复盘

    举一个最近在讨论 AppSet 分区实现的一个例子: AppSet 需要知道是否需要将换机重试这异常上报给调用方,使用错误码就会出现一个非常两难的问题: 统一加解密组件报告说,本机有问题报告异常,下次请求换机重试并返回了一个返回码...,回包带上换机重试的控制信息; 此时就出现了实现的不一致,因为步骤 6 的异常,和步骤 2 的异常并没有被完备的整体的转发给上层。...后来某些同事在尝试时,也使用了 libcurl 但并没有禁用协程也能成功,说并此次行动计划的先决条件已经不存在了,旧的行动计划由于时空环境的变化成了新的历史债务。...本人尝试重新复盘一下当时的场景。...另外一个思考点是,如果在抛出异常和捕获异常之间出现协程切换,会发生什么效果呢?我们把协程处理函数重写一下,使用 RAII 的思想在块超出作用域时进行协程切换。

    4.6K34

    Angular v18 现已推出!

    几年来,我们一直在努力寻找一种不依赖 zone.js 的 Angular 使用方式,我们非常高兴能分享第一个无区域实验性 API!从今天开始,您可以尝试 Angular 中的实验性无区域支持!...此行为仅对新应用程序启用,因为它可能会导致依赖于以前的更改检测行为的应用中出现 bug。合并减少了不必要的更改检测周期,并显著提高了某些应用程序的性能。...要预览页面上 Angular 水合的组件,您还可以启用叠加模式。如果你的应用有任何冻结错误,Angular DevTools 将在组件资源管理器中可视化它们。...社区亮点随着 Angular 的创新,我们也看到了社区中的大量进步!ngrx、ngxs 和 rxAngular 等流行的状态管理库已经在采用 Angular 信号,并在组件中实现细粒度的反应性。...Analog.js团队一直在尝试社区一直喜欢的单文件组件格式!看到来自其他生态系统的流行库构建他们的 Angular 适配器也令人兴奋。

    28110
    领券