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

React组件VerseForm报错:传入verseObj.version_id为string,预期为object

解决React组件Prop类型错误:Invalid prop verseObj.version_id of type string supplied to VerseForm, expected object

问题背景

我正在开发一款可添加经文的全栈公共祈祷日志应用,此前创建功能运行正常,近期未修改相关代码,但表单渲染时始终出现以下错误:

Invalid prop verseObj.version_id of type string supplied to VerseForm, expected object.

相关代码片段:

// VerseForm.js
useEffect(() => {
  getVersions().then(setVersions);
  if (verseObj.id) {
    getSingleVerse(verseObj.id).then((response) => {
      setCurrentVerse(response);
      // setSelectedVersion(verseObj.version_id.id);
    });
  }
}, [verseObj]);

};

const handleSubmit = (e) => {
  e.preventDefault();
  if (verseObj.id) {
    updateVerse(user, currentVerse, verseObj.id)
      .then(() => router.push('/'));
  } else {
    const payload = { ...currentVerse };
    createVerse(payload, user).then(setCurrentVerse(initialState));
  }
};


VerseForm.propTypes = {
  verseObj: PropTypes.shape({
    id: PropTypes.number,
    verse: PropTypes.string,
    content: PropTypes.string,
    version_id: PropTypes.shape({
      id: PropTypes.number,
      label: PropTypes.string,
    }),
  }),
  user: PropTypes.shape({
    uid: PropTypes.string,
    id: PropTypes.number,
  }).isRequired,
};

VerseForm.defaultProps = {
  verseObj: initialState,
};

问题原因

错误核心是父组件传给VerseForm的verseObj.version_id是字符串类型,但组件的propTypes明确要求它是包含id和label的对象。常见触发场景:

  • 后端接口返回的version_id格式变更,从关联对象变成了纯ID字符串
  • 父组件传递verseObj时,误传了version_id.id而非完整对象
  • 本地存储/状态管理中保存的verseObj数据格式异常

修复方案

1. 排查数据源

  • 检查父组件传递verseObj的逻辑,确认version_id是否为完整对象(比如列表项点击时,是否把整个版本对象传进来,而非只传ID)
  • 查看getSingleVerse接口的返回值,打印response.version_id确认格式是否符合预期

2. 组件内添加格式修正逻辑

如果无法快速修改数据源,可以在VerseForm内对传入的verseObj做容错处理:

useEffect(() => {
  getVersions().then(setVersions);
  if (verseObj.id) {
    // 修正version_id格式:如果是字符串/数字,转为符合要求的对象
    const correctedVerseObj = {
      ...verseObj,
      version_id: typeof verseObj.version_id !== 'object' 
        ? { id: Number(verseObj.version_id), label: '' }
        : verseObj.version_id
    };

    getSingleVerse(correctedVerseObj.id).then((response) => {
      setCurrentVerse(response);
      // 如果需要匹配版本名称,从已获取的versions列表中查找补全
      const matchedVersion = versions.find(v => v.id === correctedVerseObj.version_id.id);
      if (matchedVersion) {
        setSelectedVersion(matchedVersion.id);
        setCurrentVerse(prev => ({ ...prev, version_id: matchedVersion }));
      }
    });
  }
}, [verseObj, versions]);

3. 调整propTypes兼容多种格式(可选)

如果业务上允许version_id临时为数字/字符串,可以放宽propTypes限制,同时在组件内统一转换格式:

VerseForm.propTypes = {
  verseObj: PropTypes.shape({
    id: PropTypes.number,
    verse: PropTypes.string,
    content: PropTypes.string,
    version_id: PropTypes.oneOfType([
      PropTypes.shape({
        id: PropTypes.number,
        label: PropTypes.string,
      }),
      PropTypes.string,
      PropTypes.number
    ]),
  }),
  user: PropTypes.shape({
    uid: PropTypes.string,
    id: PropTypes.number,
  }).isRequired,
};

4. 修正提交逻辑

如果后端接口只需要version_id的ID值,提交时要从对象中提取:

const handleSubmit = (e) => {
  e.preventDefault();
  // 统一处理提交的version_id格式
  const formatPayload = (data) => ({
    ...data,
    version_id: data.version_id.id || data.version_id
  });

  if (verseObj.id) {
    updateVerse(user, formatPayload(currentVerse), verseObj.id)
      .then(() => router.push('/'));
  } else {
    createVerse(formatPayload(currentVerse), user)
      .then(() => setCurrentVerse(initialState));
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 05:27:45