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

在普通函数中调用React Hook是否合规?能否忽略对应ESLint警告?

能否忽略该警告?

绝对不建议忽略该警告,原因如下:

  • React Hook有严格的调用规则,只能在React函数组件、自定义Hook的顶层执行。普通工具函数checkToken的执行上下文不属于React的渲染周期,此时调用useGeneralContext根本无法获取到正确的Context上下文,轻则返回undefined,重则直接触发运行时错误,ESLint的提示不是无意义的格式校验,是在提前避免运行时报错。
  • 你当前代码里的setUserSessionExpired实际上也没有被调用,就算后续补上调用逻辑,在普通函数里调用也无法触发Context关联的组件重渲染,状态更新不会生效。
可行的修复方案

方案1:将状态更新函数作为参数传递

你可以在调用call方法的组件内先获取Context的方法,再逐层传入:

// 组件内调用call的地方
const { setUserSessionExpired } = useGeneralContext()
// 调用时传入状态更新函数
const res = await call('/api/xxx', token, data, setUserSessionExpired)

修改call和checkToken的定义,接收该参数:

const checkToken = (data, setUserSessionExpired) => {
  if (data.status === 'fail' && data.message === 'Sessione scaduta') {
    setUserSessionExpired(true) // 可以补上你遗漏的状态更新逻辑
    window.location.href = '/auth/login?session=expired';
    localStorage.removeItem('jwt');
  }
  return data;
};

export const call = async (url, token, data, setUserSessionExpired) => {
  // 原有请求逻辑不变
  const dataReturned = await fetch(url, {
    method: 'PUT',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify(data),
  })
    .then((response) => {
      return response.json();
    })
    .catch((err) => {
      return { status: 'fail', message: 'API CALL ERROR', error: err.message };
    });
  return checkToken(dataReturned, setUserSessionExpired);
};

方案2:封装请求为自定义Hook

如果不想每次调用都传参数,可以把请求方法封装成自定义Hook:

export function useRequest() {
  const { setUserSessionExpired } = useGeneralContext()
  
  const call = async (url, token, data) => {
    const dataReturned = await fetch(url, {
      method: 'PUT',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
        Authorization: `Bearer ${token}`,
      },
      body: JSON.stringify(data),
    })
      .then((response) => {
        return response.json();
      })
      .catch((err) => {
        return { status: 'fail', message: 'API CALL ERROR', error: err.message };
      });

    if (dataReturned.status === 'fail' && dataReturned.message === 'Sessione scaduta') {
      setUserSessionExpired(true)
      window.location.href = '/auth/login?session=expired';
      localStorage.removeItem('jwt');
    }
    return dataReturned
  }
  
  return { call }
}

组件内使用方式:

const { call } = useRequest()
// 直接调用call即可,不需要额外传状态更新方法
const res = await call('/api/xxx', token, data)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:06:03