Как уже упоминалось, это, вероятно, страшная идея, но в спирте «все возможно», вот оно.
Сначала нам нужно определить интерфейс для тестирования опоры. Это полностью гибко, с удобством по умолчанию.
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}
где нечетные возвращает истину, если число нечетное. Когда вызывается с <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, который возвращает строку, и ни один из Mixins не активны, это будет тихо вернуться неопределенными
jsbin
Это выглядит как главный кандидат, чтобы сделать два компонента. Я согласен с тем, что вы не хотите, чтобы в компоненте было много условностей - обычно много условностей вокруг одного или двух значений центральной опоры является хорошим индикатором того, что компонент можно реорганизовать и разделить, чтобы упростить. –
Похоже, что у вас уже есть поддержка: как насчет определения функции, которая определяет компонент с помощью prop в качестве параметра, сначала вычислите список 'mixins' в этом« компоненте, определяющем », затем передайте результаты вашей функции 'react.renderComponent'? Например. 'Реагировать.renderComponent (componentDefiningFunc (prop), yourTarget) ' –