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

TypeScript中Generator函数(yield)无法配合自定义Hook使用怎么办?

问题分析与解决方案

核心问题

React Hooks 只能在React函数组件或自定义React Hook函数的顶层调用,而你用的calling是Redux-Saga的Generator副作用函数,完全不属于React组件/Hook环境,直接调用useCustom会触发Hook规则报错;你封装的普通函数Custom里调用useCustom同样违反规则,导致Hook逻辑未正常执行,字符串替换功能失效。

解决思路

将useCustom中字符串替换的核心逻辑从Hook中抽离成独立工具函数,既可以在React Hook中复用,也能直接在Saga的Generator函数里调用(无需依赖React环境)。

步骤1:抽离核心替换逻辑

假设原useCustom内部是读取JSON文件实现字符串替换,把这部分逻辑单独提取:

// utils/customString.ts
import { Stringable } from '../types';

// 替换为你实际的JSON文件路径或动态读取逻辑
const customLocaleData = require('../locales.json');

export const getCustomString = (key: string, replace?: Stringable[]): string => {
  // 获取对应key的替换文本,未找到则返回原key
  const targetText = customLocaleData[key] || key;
  
  // 处理占位符替换(示例:{0}、{1}格式)
  if (!replace?.length) return targetText;
  return targetText.replace(/\{(\d+)\}/g, (_, index) => {
    const replacement = replace[Number(index)];
    return replacement != null ? String(replacement) : _;
  });
};

步骤2:重构原useCustom Hook

让Hook复用抽离的工具函数,保留React环境下的使用能力:

// hooks/useCustom.ts
import { Stringable } from '../types';
import { getCustomString } from '../utils/customString';

export const useCustom = () => {
  // 如果原Hook有依赖React状态/上下文的逻辑(比如语言切换监听),可保留在此处
  // 示例:const locale = useContext(LocaleContext);
  
  return (key: string, replace?: Stringable[]): string => {
    return getCustomString(key, replace);
    // 若有上下文依赖,可改为:return getCustomString(key, replace, locale);
  };
};

步骤3:在Generator函数中直接使用工具函数

现在可以在calling里直接调用工具函数,完全避开Hook规则限制:

import { getCustomString } from './utils/customString';

export function* calling(action: any) {
  try {
    const message = getCustomString('Template applied.');
    yield call(status, message, StatusType.success);
  } catch (e) {
    yield put(getFail(e));
  }
}

特殊场景处理(若原Hook依赖React上下文)

如果原useCustom依赖React上下文(比如多语言切换的LocaleContext),可将上下文状态同步到Redux store,在Saga中通过select获取:

// 在Saga中获取Redux存储的语言状态
import { select } from 'redux-saga/effects';
import { getCurrentLocale } from './store/selectors'; // 自定义selector

export function* calling(action: any) {
  try {
    const locale = yield select(getCurrentLocale);
    const message = getCustomString('Template applied.', [], locale); // 调整工具函数支持locale参数
    yield call(status, message, StatusType.success);
  } catch (e) {
    yield put(getFail(e));
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:55:26