You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxJS流中使用Immer produce操作对象失败,求解决方案

解决方案

核心问题

你遇到的报错是因为sessionAction.payload是Observable类型,而Immer的produce仅支持处理普通可draft对象(如纯对象、数组),所以必须先提取出Observable内部的实际数据值。


具体解决方法

1. 在switchMap中嵌套处理payload的Observable

如果sessionAction.payload本身就是Observable,需要在外部流中先订阅这个内部Observable,拿到它发射的实际数据后再调用Immer:

import { switchMap, of } from 'rxjs';
import { produce } from 'immer';

// 假设yourMergedAction$是你合并后的Action流
yourMergedAction$.pipe(
  switchMap(sessionAction => 
    // 先订阅payload这个Observable,获取实际值
    sessionAction.payload.pipe(
      switchMap(payloadValue => {
        // 这里payloadValue就是普通对象,可直接传给produce
        const updatedState = produce(yourCurrentState, draft => {
          draft.session = payloadValue; // 示例修改逻辑
        });
        return of(updatedState); // 返回新状态的Observable
      })
    )
  )
);

2. 检查Action创建逻辑

排查你创建Action的代码,是否误将Observable作为payload传入。正常的Action payload应该是普通数据:

// ❌ 错误:payload是Observable
const badAction = { type: 'SESSION_UPDATED', payload: fetchSessionData() };

// ✅ 正确:payload是普通对象/数据
fetchSessionData().subscribe(data => {
  const goodAction = { type: 'SESSION_UPDATED', payload: data };
});

3. 利用state-adapt内置的Immer支持

state-adapt本身集成了Immer,无需手动调用produce。你可以直接在状态适配器的handler中编写Immer风格的修改逻辑,框架会自动处理payload:

import { adapt } from '@state-adapt/rxjs';

const sessionAdapter = adapt({
  initialState: { userId: '', token: '' },
  handlers: {
    // 这里的payload已经是普通对象,直接修改状态即可
    UPDATE_SESSION: (state, payload) => {
      state.userId = payload.userId;
      state.token = payload.token;
    }
  }
});

// 将你的Action流传入适配器
sessionAdapter.actions(yourMergedAction$);

内容的提问来源于stack exchange,提问作者J King

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:06:00