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

如何在TypeScript的React自定义Hook中传参?解决TS2345报错

问题:调用自定义Hook传递字符串时出现TypeScript类型错误

我尝试在调用自定义Hook时传入一个字符串(比如指定JSON文件路径)来获取对应数据,但即使定义了Prop类型,还是报错:TS2345: Argument of type 'string' is not assignable to parameter of type '{ string: any; }',这是为什么?


1. 自定义Hook代码

import axios from 'axios';
import React, { FC } from 'react';
import { useState, useEffect } from 'react'

interface APICallProps {
    apiCall: string
}

const useFetchSecurityData = ({ string: apiCall }) => {
    const [loading, setLoading] = useState<boolean>(true)
    const [data, setData] = useState<null>(null)

    useEffect(() => {
        fetchData()
    }, [])

    const fetchData = async () => {
        axios.get(apiCall)
            .then(res => {
                setData(res.data)
            })
            .catch(err => console.error(err))
        setLoading(false)
    }

    return { data, loading }
}

export default useFetchSecurityData

2. 页面中调用Hook的代码

const ChartArea = () => {
  const [incidents, setIncidents] = useState([])
  const { data, loading } = useFetchSecurityData('incidents.json')
  // const { data, loading } = useFetchIncidents()

  useEffect(() => {
    fetchData()
  }, [loading, data])

  const fetchData = () => {
    try {
      let rawData = (data) ?? []
      setIncidents(rawData)
    } catch (err) {
      console.error(err)
    }
  }
}

原因及修复方案

错误原因

你的自定义Hook useFetchSecurityData 参数定义存在矛盾:

  • 你声明了接口 APICallProps 包含 apiCall 字符串字段,但实际函数参数用了对象解构的错误写法 { string: apiCall },这意味着Hook期望接收一个包含string属性的对象,而非直接传入字符串。
  • 但调用时你传的是原始字符串 'incidents.json',TypeScript自然会报类型不匹配错误。

修复步骤

根据需求,有两种修复方式:

方式一:让Hook接收对象参数(匹配定义的APICallProps接口)

  1. 修正Hook的参数解构,对齐接口字段:
// 把 { string: apiCall } 改成 { apiCall },对应APICallProps的字段
const useFetchSecurityData = ({ apiCall }: APICallProps) => {
  // ... 其余代码不变
}
  1. 调用Hook时传入对象:
const { data, loading } = useFetchSecurityData({ apiCall: 'incidents.json' })

方式二:让Hook直接接收字符串参数(更简洁)

如果不需要传递多个参数,直接让Hook接收字符串即可:

  1. 修改Hook的参数定义:
// 去掉APICallProps接口,直接定义参数为string类型
const useFetchSecurityData = (apiCall: string) => {
  // ... 其余代码不变
}
  1. 调用方式保持不变:
const { data, loading } = useFetchSecurityData('incidents.json')

额外优化点

你的fetchData函数存在逻辑问题:setLoading(false)写在axios请求外部,会导致请求未完成就将loading设为false,建议调整为:

const fetchData = async () => {
  try {
    const res = await axios.get(apiCall)
    setData(res.data)
  } catch (err) {
    console.error(err)
  } finally {
    setLoading(false)
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:55:16