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

ReactJS使用fetch调用下载接口报Cannot read properties错误求助

排查方向

  • 你贴出的代码中没有出现payload字段,首先打开浏览器控制台的报错堆栈,定位到具体是哪一行代码在读取payload属性,确认该属性所属的对象为什么是undefined。
  • 你标注为reducer实现的printedPin函数不符合Redux reducer的规范:reducer必须是无副作用的纯函数,不能包含异步请求、DOM操作这类逻辑。你现在的写法是Redux Thunk异步action的逻辑,大概率是你错误地把它放在了reducer文件中,且没有按Thunk的规范编写、绑定,导致后续接收action的逻辑拿到的是undefined,读取payload时触发报错。
  • 现有fetch请求的错误处理存在缺失:fetch只有在网络断连等极端情况才会抛错,接口返回4xx/5xx状态码时不会进入catch逻辑,你没有判断response.ok就直接调用blob(),如果接口返回错误响应,后续处理逻辑可能拿到不符合预期的结果,引发报错。

修复方案

  1. 修正异步action的写法,按Redux Thunk规范调整printedPin的实现,补全错误处理(该函数属于异步action,不应该放在reducer文件中,建议移到单独的action文件里):
export const printedPin = (id, callback) => async (dispatch) => {
  try {
    const requestUrl = `${apiUrl}/${id}/printpin`
    const response = await fetch(requestUrl)
    // 先判断请求状态是否正常
    if (!response.ok) throw new Error(`请求失败,状态码:${response.status}`)
    
    const blob = await response.blob()
    if (blob.type === 'application/problem+json') {
      callback()
      // 如果需要派发错误action,确保payload字段存在
      dispatch({ type: 'PRINT_PIN_ERROR', payload: { msg: '业务请求失败' } })
      return
    }
    // 下载逻辑
    const url = window.URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = 'pin.pdf'
    a.click()
    window.URL.revokeObjectURL(url) // 释放对象URL占用的内存
    dispatch({ type: 'PRINT_PIN_SUCCESS', payload: { success: true } })
  } catch (err) {
    console.error('打印请求错误:', err)
    callback()
    dispatch({ type: 'PRINT_PIN_ERROR', payload: { msg: err.message } })
  }
}
  1. 调整reducer中的处理逻辑,访问payload前添加非空判断:
const initialState = {
  loading: false,
  success: false,
  error: null
}

export const pinReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'PRINT_PIN_SUCCESS':
      // 使用可选链避免读取undefined的属性
      return { ...state, success: action?.payload?.success ?? false, error: null }
    case 'PRINT_PIN_ERROR':
      return { ...state, error: action?.payload?.msg ?? '未知错误', success: false }
    default:
      return state
  }
}
  1. 修正组件中调用异步action的方式,不要直接调用props里的函数,要通过dispatch触发:
import { useDispatch } from 'react-redux'
import { printedPin } from '你的action文件路径'

const YourComponent = () => {
  const dispatch = useDispatch()
  // 其他组件逻辑...
  const printPin = event => {
    event.preventDefault()
    // 把异步action传给dispatch,由Redux Thunk中间件处理执行
    dispatch(printedPin(scePersonaEntity.perCod, activateAlert))
  }
  // 渲染逻辑...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:54:03