Week 08 · Day 03 — 簡單狀態管理:BehaviorSubject
學習目標
- 用
BehaviorSubject管理共享狀態 - 用
.next()更新狀態、.asObservable()安全暴露 - 元件訂閱取得最新狀態
重點
為什麼需要狀態管理 - 多個元件要共享資料(如登入狀態、待辦清單) - 保證資料「單一來源」(single source of truth)
StateService
import { BehaviorSubject, Observable } from 'rxjs';
interface AppState {
user: User | null;
todos: Todo[];
loading: boolean;
}
@Injectable({ providedIn: 'root' })
export class StateService {
private state: AppState = {
user: null,
todos: [],
loading: false
};
private state$ = new BehaviorSubject(this.state); // 初始值必填
getState(): Observable<AppState> {
return this.state$.asObservable(); // 外界只能讀,不能直接 next
}
setUser(user: User | null): void {
this.state = { ...this.state, user }; // 不可變更新
this.state$.next(this.state);
}
addTodo(todo: Todo): void {
this.state = {
...this.state,
todos: [...this.state.todos, todo]
};
this.state$.next(this.state);
}
}
為什麼 BehaviorSubject - 需給初始值 - 訂閱者一訂閱就「立刻收到目前值」 - (相比 subject 只推之後的值)
用 spread 保持不可變
- 避免直接修改原物件,用 ... 生出新版後才指派
實作
- 建立
StateService,含user/todos/loading - 實作
setUser/addTodo - 建立元件訂閱
getState()觀察更新
作業
- 用
BehaviorSubject建立共享狀態 - 用
.next()更新,asObservable()暴露 - 用 spread 做到不可變更新