我有一个函数可以转换其他函数:
//library:
let transform = function(OriginalComponent) {
let WrappedComponent (props) => {
//some transformation
return <OriginalComponent {...props} />
};
//I specifically need the original component to have a NON EMPTY name here
Object.defineProperty(WrappedComponent, "name", { value: OriginalComponent.name });
}
我目前在一个类似的文件中使用这个
export const MyWrappedComponent = transform(function MyComponent(props){
return <h1>Hello {props.name}!</h1>;
});
有了这个设置,我目前需要使用不同的名称来导出和函数。
我的问题是:我能以某种方式在一行中导出它吗,只使用一个名称而不是两个名称
我试过了:
export function transform(function MyComponent(props){
return <h1>Hello {props.name}!</h1>;
});
但这是无效的,因为导出没有名称。
我还想到了
export const MyComponent = transform((props) => {
return <h1>Hello {props.name}!</h1>;
});
但随后transform()
接收到一个未命名的组件(我认为它无法知道导出名称?(
这是关于库的标准,所以我希望尽可能保持示例的整洁。命名一个函数,然后命名导出可能会让人感到困惑。如果必须同时命名,我更愿意使用相同的名称,但我不知道如何命名。
如果你想使用命名导出,并且你想将函数直接传递到transform
,你就不能(合理地(重复这个名称,比如:
export const MyComponent = transform(function MyComponent(props){
return <h1>Hello {props.name}!</h1>;
});
使用此设置,我当前需要为导出和函数使用不同的名称。
谢天谢地,你没有;如上所述,在那里使用相同的名称是完全有效的。
值得一提的是,我注意到transform
函数有几个问题:
不能直接写入函数的
name
属性,它是只读的。但是您可以通过Object.defineProperty
替换属性(因为它是可配置的(。它不是返回封装的组件。
这是一个修复了这些问题的版本:
export let transform = function (OriginalComponent) {
let WrappedComponent = (props) => {
//some transformation
return <OriginalComponent {...props} />;
};
// I specifically need the original component to have a NON EMPTY name here
Object.defineProperty(WrappedComponent, "name", {
value: OriginalComponent.name,
});
return WrappedComponent;
};
在Object.defineProperty
调用中,我没有指定任何标志(writable
、configurable
、enumerable
(,因此将使用上一个属性中的标志。(属性为configurable
,但不是writable
或enumerable
。(
作为替代方案,您可以将展开的组件放在一个对象中:
export const components = {
MyComponent(props) {
return <h1>Hello ${props.name}!</h1>;
},
// ...
};
然后进行后处理:
for (const [name, component] of Object.entries(components)) {
components[name] = transform(component);
}
但这意味着您的导出是components
对象,而不是单个组件,因此您最终会使用以下用法:
import { components } from "./somewhere";
const { MyComponent } = components;
// ...
这不太理想。(遗憾的是,你不能直接销毁进口。(