使用ngrx select时遇错误:Angular Material侧边栏状态管理问题
Hey there! Let's work through this TypeScript error you're hitting when trying to manage your mat-sidenav's opened state with NgRx. That TS2345 error tells us there's a type mismatch between the action type you're dispatching and what your NgRx setup expects—most likely a typo or incorrect action string being used.
Here's what's probably going wrong and how to fix it:
Check your NgRx Action Definition
You should have defined an action to handle setting the sidenav's opened state using NgRx'screateAction. If you haven't, start with something like this:// src/app/store/sidenav.actions.ts import { createAction, props } from '@ngrx/store'; // This action type is what your store expects export const setSidenavOpened = createAction( '[Sidenav] Set Opened State', props<{ opened: boolean }>() );The key here is the first argument (
'[Sidenav] Set Opened State')—this is the unique type identifier for your action.Fix the Dispatch Call in Your Component
The error points to line 21 indocs.component.ts, which means you're probably dispatching an action with the wrong type string. Instead of hardcoding'opened', use the action creator you defined:// src/app/docs/docs.component.ts import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { setSidenavOpened } from '../store/sidenav.actions'; @Component({ selector: 'app-docs', templateUrl: './docs.component.html' }) export class DocsComponent implements OnInit { constructor(private store: Store) {} ngOnInit(): void { // Dispatch the action using the creator (avoids type mismatches) this.store.dispatch(setSidenavOpened({ opened: true })); } }Using the action creator ensures you're using the exact type string your store is expecting, eliminating the type error.
Verify Your Reducer Setup
Make sure your reducer is listening for the correct action type (via the action creator) to update the state:// src/app/store/sidenav.reducer.ts import { createReducer, on } from '@ngrx/store'; import { setSidenavOpened } from './sidenav.actions'; export interface SidenavState { opened: boolean; } export const initialState: SidenavState = { opened: true // Your initial state }; export const sidenavReducer = createReducer( initialState, on(setSidenavOpened, (state, { opened }) => ({ ...state, opened })) );Bind the State to mat-sidenav
Finally, make sure you're subscribing to the store state to bind to the mat-sidenav'sopenedproperty:<!-- src/app/docs/docs.component.html --> <mat-sidenav [opened]="sidenavOpened$ | async"> <!-- Your sidenav content here --> </mat-sidenav>// In docs.component.ts, add this: import { Observable } from 'rxjs'; import { selectSidenavOpened } from '../store/sidenav.selectors'; sidenavOpened$: Observable<boolean>; ngOnInit(): void { this.sidenavOpened$ = this.store.select(selectSidenavOpened); // Only dispatch if you need to override the initial state // this.store.dispatch(setSidenavOpened({ opened: true })); }
Quick Summary
The root cause is that you were dispatching an action with a type string ('opened') that doesn't match what your NgRx action/reducer is configured to handle. Using NgRx's action creators removes the risk of typos and ensures type safety, which fixes the TypeScript error.
内容的提问来源于stack exchange,提问作者OscarRP

