向 React 17+ 中的枚举添加函数(使用函数组件)
Add functions to an enum in React 17+ (with functional components)
我想在我的 React 函数式组件(即 classless)TypeScript 项目中向枚举类型添加函数。
与 一样,这可以通过以下两种方式之一完成:
class ModeUtil {
public static toString(mode: Mode) {
return Mode[mode];
}
或
enum Mode {
X,
Y
}
namespace Mode {
export function toString(mode: Mode): string {
return Mode[mode];
}
export function parse(mode: string): Mode {
return Mode[mode];
}
}
因为到目前为止我已经能够在我的项目中避免 classes,所以我更喜欢保持这种方式,因此我赞成命名空间方法。
但是,命名空间方法违反了 no-namespace ESLint 规则。
因此,使用 class 毕竟是一种有效的方法吗?我的意思是,在 React 中,函数式组件被引入以支持基于 class 的组件以避免突变问题。在这种情况下,class 本身将只包含静态方法...
我不认为 React 选择远离 classes 意味着“一般来说,classes 是不好的,应该避免”。
它只是意味着“在 React 中,组件可以用函数组件更好地表达和轻松定义”。
所以回答你的问题:classes 是一般有效的方法。
但是您需要了解它是否适合您的情况。
在你的具体情况下,我认为它可以顺利工作。或者,如果您不这么认为,您可以禁用该 eslint 规则。
但是,React 拒绝基于 class 的组件这一事实并不意味着 class 是不好的。只需使用 React 功能组件,只要您认为它们可以提供帮助,请随意使用 classes。
所以我最终得到了一个没有命名空间或模块名称的模块(即非 class 特定)方法。这确保我符合 no-namespace ESLint 规则,并且我可以在不引入 classes.
的情况下保持我的代码库干净
鉴于您有这样的 Drink 枚举:
export enum Drink {
GinTonic,
LongIslandIceTea
}
然后您可以像这样定义 utils/helper 函数:
import { Drink } from "../models/drink";
const toHumanString = (drink: Drink): string => {
switch (drink) {
case Drink.GinTonic:
return "Gin Tonic";
case Drink.LongIslandIceTea:
return "Long Island Ice Tea";
default:
throw new Error(`Unknown drink ${drink}.`);
}
};
const toMachineString = (drink: Drink) => {
switch (drink) {
case Drink.GinTonic:
return "GinTonic";
case Drink.LongIslandIceTea:
return "LongIslandIceTea";
default:
throw new Error(`Unknown drink ${drink}.`);
}
};
const parse = (drinkAsString: string): Drink => {
switch (drinkAsString) {
case "GinTonic":
return Drink.GinTonic;
case "LongIslandIceTea":
return Drink.LongIslandIceTea;
default:
throw new Error(`Failed to parse drink ${drinkAsString}.`);
}
};
export const DrinkUtils = {
parse: parse,
toHumanString: toHumanString,
toMachineString: toMachineString
};
我添加了一个演示 here。
这就像使用静态方法的 class,因为 DrinkUtil
对象在编译时在 IDE 中可用。
我想在我的 React 函数式组件(即 classless)TypeScript 项目中向枚举类型添加函数。
与
class ModeUtil {
public static toString(mode: Mode) {
return Mode[mode];
}
或
enum Mode {
X,
Y
}
namespace Mode {
export function toString(mode: Mode): string {
return Mode[mode];
}
export function parse(mode: string): Mode {
return Mode[mode];
}
}
因为到目前为止我已经能够在我的项目中避免 classes,所以我更喜欢保持这种方式,因此我赞成命名空间方法。
但是,命名空间方法违反了 no-namespace ESLint 规则。
因此,使用 class 毕竟是一种有效的方法吗?我的意思是,在 React 中,函数式组件被引入以支持基于 class 的组件以避免突变问题。在这种情况下,class 本身将只包含静态方法...
我不认为 React 选择远离 classes 意味着“一般来说,classes 是不好的,应该避免”。 它只是意味着“在 React 中,组件可以用函数组件更好地表达和轻松定义”。
所以回答你的问题:classes 是一般有效的方法。 但是您需要了解它是否适合您的情况。 在你的具体情况下,我认为它可以顺利工作。或者,如果您不这么认为,您可以禁用该 eslint 规则。
但是,React 拒绝基于 class 的组件这一事实并不意味着 class 是不好的。只需使用 React 功能组件,只要您认为它们可以提供帮助,请随意使用 classes。
所以我最终得到了一个没有命名空间或模块名称的模块(即非 class 特定)方法。这确保我符合 no-namespace ESLint 规则,并且我可以在不引入 classes.
的情况下保持我的代码库干净鉴于您有这样的 Drink 枚举:
export enum Drink {
GinTonic,
LongIslandIceTea
}
然后您可以像这样定义 utils/helper 函数:
import { Drink } from "../models/drink";
const toHumanString = (drink: Drink): string => {
switch (drink) {
case Drink.GinTonic:
return "Gin Tonic";
case Drink.LongIslandIceTea:
return "Long Island Ice Tea";
default:
throw new Error(`Unknown drink ${drink}.`);
}
};
const toMachineString = (drink: Drink) => {
switch (drink) {
case Drink.GinTonic:
return "GinTonic";
case Drink.LongIslandIceTea:
return "LongIslandIceTea";
default:
throw new Error(`Unknown drink ${drink}.`);
}
};
const parse = (drinkAsString: string): Drink => {
switch (drinkAsString) {
case "GinTonic":
return Drink.GinTonic;
case "LongIslandIceTea":
return Drink.LongIslandIceTea;
default:
throw new Error(`Failed to parse drink ${drinkAsString}.`);
}
};
export const DrinkUtils = {
parse: parse,
toHumanString: toHumanString,
toMachineString: toMachineString
};
我添加了一个演示 here。
这就像使用静态方法的 class,因为 DrinkUtil
对象在编译时在 IDE 中可用。