angular - 分派到状态时,Angular NGRX 出错
问题描述
我第一次使用 Ngrx,虽然它相对简单,但在调度状态时出现错误。当用户打开应用程序时,他需要输入他的姓名并提交,下一个屏幕应该显示“问候{{用户名}}”。用户提交后,我收到此错误-> core.js:6014 ERROR TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
感谢你的帮助
import { Action } from '@ngrx/store';
import { UserName, WishListItem } from 'src/model/name.model';
export enum AddToStateActionType{
ADD_NAME = '[ADD_NAME] add name',
ADD_TO_WISHLIST = '[ADD_TO_WISHLIST] add to wishlist'
}
export class AddWelcomeNameAction implements Action {
readonly type = AddToStateActionType.ADD_NAME;
constructor(public payload: UserName){}
}
export class AddToWishList implements Action {
readonly type = AddToStateActionType.ADD_TO_WISHLIST;
constructor(public payload: WishListItem){}
}
export type UserAction = AddWelcomeNameAction | AddToWishList ;
<!--Reducer-->
import {AddToStateActionType, UserAction} from './../action/action';
import { UserName, WishListItem } from 'src/model/name.model';
const initialState: any = {
name: '',
wishlist: []
};
export function reducer(state: any = initialState, action: any) {
switch(action.type) {
case AddToStateActionType.ADD_NAME:
return [...state, action.payload.name];
case AddToStateActionType.ADD_TO_WISHLIST:
return [...state. action.payload.wishlist];
default:
return state;
}
}
<!--AppState-->
import { UserName, WishListItem } from 'src/model/name.model';
export interface AppState {
readonly username: UserName;
readonly wishlist: Array<WishListItem> ;
}
<!--Welcome component-->
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '../app.state/app.state';
import * as Actions from '../../action/action';
import {Router} from '@angular/router';
import { UserName } from 'src/model/name.model';
@Component({
selector: 'app-welcome',
templateUrl: './welcome.component.html',
styleUrls: ['./welcome.component.css']
})
export class WelcomeComponent implements OnInit {
userName: UserName = {name: ''};
profileForm = new FormGroup({
userName: new FormControl(''),
});
constructor(private store: Store<AppState>, private router: Router) { }
ngOnInit() {
}
onSubmit() {
this.store.dispatch(new Actions.AddWelcomeNameAction({name: this.profileForm.value}));
this.router.navigate(['/search']);
}
}
解决方案
对于这两种情况,问题都出在你的减速器上。
在您的代码中:
export function reducer(state: any = initialState, action: any) {
switch(action.type) {
case AddToStateActionType.ADD_NAME:
return [...state, action.payload.name];
case AddToStateActionType.ADD_TO_WISHLIST:
return [...state. action.payload.wishlist];
default:
return state;
}
}
您错误地应用了扩展运算符,导致两个问题:
数组扩展运算符:您正在应用数组扩展运算符:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax 。
[...state, action.payload.name]; // This is an array
该运算符的工作方式如下:
let a = [1, 2, 3];
let b = 4;
let c = [...a, b]; // Here we will add each item of a and then b resulting in c = [1, 2, 3, 4]
因此,运行时将尝试“迭代”状态,但状态是一个对象,而不是一个数组。这是第一个错误。
Reducer 返回类型:在默认情况下,您将按预期返回原始状态,但在这两种情况下,您实际上都返回了一个数组。
作为一个好的实践,如果你明确指定 reducer 的返回类型,你会看到 TypeScript 是如何抱怨它的。
解决方案: 要修复您的代码,您应该将您的 reducer 重写为:
case AddToStateActionType.ADD_NAME:
// Here you return a copy of state and overwrite the name property.
return {
...state,
name: action.payload.name,
};
case AddToStateActionType.ADD_TO_WISHLIST:
// Here you return a copy of state and overwrite the wishlist property with the same elements + the new one.
return {
...state,
wishlist: [...state.wishlist, action.payload.wishlist]
};
推荐阅读
- python-3.x - 使用 cv2 进行灰度图像旋转
- php - 如何将本地文件夹的多个文件上传到ftp文件夹?
- excel - 自动格式化提前结束
- c - 如何将 Python 字符串列表转换为 wchar_t 的 C 数组?
- python - 无法在评论删除页面显示帖子标题
- docker - Docker 中的 Kubernetes 集群是什么?
- r - 在 dplyr 管道中加入非 R 标准列名
- arrays - 在 ruby 中,如何用 id 键重新排列对象数组,将数组的新顺序作为数组给出?
- java - 无法连接到 Postgres SQL,使用 Jmeter JDBC 连接
- google-maps - 通过 Google Distance Matrix API 和 Google Map API 计算的距离