是否可以基于道具为React组件构建mixin数组?
我有一个带有道具的组件,它可以取两个值中的一个。基于此,我需要与我的一个mixin完全不同的行为。我想把这个mixin分成两个单独的文件,而不是到处都有可怕的条件语句,但我找不到一个简单的方法来做到这一点。有什么建议吗?
不,这是不可能的。在不了解更多信息的情况下,听起来您可能想探索创建不同组件并有条件地使用父组件的正确组件的想法。如果你愿意的话,你甚至可以把它包装起来,对消费者隐瞒。
正如其他人所提到的,这可能是一个可怕的想法,但从"一切皆有可能"的精神来看,它就是这样。
首先,我们需要定义一个用于测试道具的接口。它是完全灵活的,有一个方便的默认值。
var hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
function testProps(obj, thisArg){
return Object.keys(obj).every(function(propName){
var test = obj[propName], prop = thisArg.props[propName];
if (typeof test === "function"){
return test(prop);
}
else {
return prop === test;
}
});
}
传递给它的一个例子是{foo: true, bar: odd}
,如果一个数字是奇数,则奇数返回true。当使用<Component foo={true} bar={7} />
调用时,mixin将处于"活动"状态。
使用它,我们可以定义一个接受{mixin: mixin, condition: tests}
数组的函数,其中测试采用上述格式。
function conditionalizeMixins(mixins){
var proxyMixin = {};
var runMixins = function(lifeCycleKey){
return function(){
var component = this, args = arguments;
var result;
mixins.forEach(function(mixin){
if (testProps(mixin.condition, component)) {
result = mixin.mixin[lifeCycleKey].apply(component, args);
}
});
return result;
}
}
mixins.forEach(function(mixin){
Object.keys(mixin.mixin).forEach(function(key){
if (proxyMixin[key]) return;
proxyMixin[key] = runMixins(key);
});
});
return proxyMixin;
}
现在我们可以这样定义我们的混合体:
mixins: [conditionalizeMixins([
{
mixin: myMixin,
condition: {foo: true, bar: false}
},
{
mixin: myMixin,
condition: {foo: false, num: function(x){return x%2===1}}
}
])]
看看是否有办法将其拆分为两个组件,而不是单个组件。这可能是最好的方法。
关于上述代码的注意事项:
- 性能不太好,但可以优化
- 如果定义了多个条件混合,例如getInitialState,则只使用最后一个活动的
- 它隐藏错误,例如,如果您定义了返回字符串的doFoo,并且没有一个mixin处于活动状态,它将静默地返回undefined
jsbin
本机没有,最好根据条件构建单独的组件。然而,有一个名为react mixin manager的第三方组件,它可以根据条件和接受参数的mixin进行动态mixin。然而,我还没有使用过它,所以我不能真正保证它,我也不建议在生产网站上使用它,但可以随意使用