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

使用Redux Toolkit检测到状态中非序列化值的问题排查

问题分析与解决方案

错误核心原因

你遇到的非序列化值错误和res.json无关,后端返回数据的方式是正确的。问题出在两个关键地方:

  1. Redux状态存了React元素:Redux要求状态必须是可序列化的纯数据(对象、数组、字符串、数字等),但你在morphemeCheck2里直接返回<span>这类React元素,还把结果存在preppedWord状态里,这直接触发了非序列化值检测错误。
  2. 异步逻辑误用:prefixCheck是异步函数(依赖api.getPrefixes().then()),但你在同步的reducer和JSX渲染里直接调用它,会返回Promise而非预期的内容,同时reducer本身不允许执行异步操作。

分步解决方案

1. 重构Redux状态:只存纯数据

把preppedWord改成存储词素分析后的纯数据结构,而非JSX元素:

const wordSlice = createSlice({
  name: 'word',
  initialState: { 
    word: '', 
    preppedWord: [] // 改为存储词素数据数组,比如[{prefix: "", base: "", suffix: ""}, ...]
  },
  reducers: {
    setWord(state, action) {
      state.word = action.payload
    },
    setPreppedWord(state, action) {
      state.preppedWord = action.payload // 只存纯数据
    },
    // ...其他reducer逻辑
  })

2. 把异步词素处理移到Redux异步Action中

Redux reducer必须是纯同步函数,异步逻辑要放到Thunk(Redux Toolkit默认集成)里:

// 异步Action:先获取前缀/后缀数据,再处理词素拆分
export const fetchAndCheckMorphemes = (word) => async (dispatch) => {
  try {
    // 异步获取数据库中的前缀、后缀数据
    const prefixes = await api.getPrefixes();
    const suffixes = await api.getSuffixes(); // 假设你有对应的后缀接口

    // 拆分词素,生成纯数据数组
    const preppedData = word.split(' ').map((wordItem) => {
      let prefix = '';
      // 匹配前缀
      for (let p of prefixes) {
        if (wordItem.startsWith(p.affix_name)) {
          prefix = p.affix_name;
          break;
        }
      }

      // 计算词根(去掉前缀后)
      let base = prefix ? wordItem.slice(prefix.length) : wordItem;
      let suffix = '';
      // 匹配后缀
      for (let s of suffixes) {
        if (base.endsWith(s.affix_name)) {
          suffix = s.affix_name;
          base = base.slice(0, base.length - suffix.length);
          break;
        }
      }

      return { prefix, base, suffix };
    });

    // 把处理后的纯数据存入Redux状态
    dispatch(setPreppedWord(preppedData));
  } catch (err) {
    console.error('词素处理失败:', err);
  }
}

3. 在组件中根据Redux数据渲染JSX

组件从Redux拿到纯数据后,再在组件内部渲染对应的DOM元素:

import { useDispatch, useSelector } from 'react-redux';
import { setWord, fetchAndCheckMorphemes } from './wordSlice';

function WordAnalyzer() {
  const dispatch = useDispatch();
  const { word, preppedWord } = useSelector(state => state.word);

  const handleInputChange = (e) => {
    const newWord = e.target.value;
    dispatch(setWord(newWord));
    // 触发异步词素分析
    dispatch(fetchAndCheckMorphemes(newWord));
  };

  return (
    <div>
      <input value={word} onChange={handleInputChange} placeholder="输入单词" />
      <div className="word-breakdown">
        {preppedWord.map((item, index) => (
          <span key={index}>
            {item.prefix && <span className={`prefix ${item.prefix}`}>{item.prefix}</span>}
            <span className="base-word">{item.base}</span>
            {item.suffix && <span className={`suffix ${item.suffix}`}>{item.suffix}</span>}
          </span>
        ))}
      </div>
    </div>
  );
}

后端代码无需修改

你的后端router.get('/prefixes')用res.json(result)返回数据是完全正确的,这不是问题所在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:20:56