var A = { doStuff (){} } var B = { doStuff (){} } var C = React.createClass({ mixins: [A, B] }); //упс... ошибка, потому что React не может решить какой из doStuff унаследовать
К тому же, миксины не позволяют делать стандартные ООПешные фишки вроде перезаписи методов(method override):
var A = { doStuff (){} } var C = React.createClass({ mixins: [A], doStuff (){ //неа, не получится } });
А без этого, естественно, не сработает и расширение функционала как во «взрослых» ООП языках:
doStuff (){ super.doStuff() //дополнительный функционал }
Конечно, классы ES6 решат эту проблему, и команда ReactJS к этому готовится, если судить по постам на их блоге, но ждать ES6 придется как второго пришествия, а затем, придется еще подождать пока не вымрут старые Интернет Эксплореры без поддержки ES6.
Итак, я хочу предложить вам альтернативный метод, который и сам использую, но для этого вам понадобятся:
1) Система модулей/зависимостей: RequireJS/Browserify/WebPack/что там еще сейчас в моде. Если вы не пользуетесь/не знаете что такое JavaScript модули, что ж, самое время узнать.
2) Какая-нибудь функция/либа для глубокого копирования объектов, например, jQuery.extend, _.extend и т.п.
Итак, я пишу модули своих компонент следующим образом:
var React = require('react'); var Human = { whoAreYou (){ return "I'm a human"; } whatDoYouDo (){ return "I'm just chilling"; } render (){ return ( <h1>{this.whoAreYou()}<small>{this.whatDoYouDo()}</small></h1> ) } } module.exports = { Class: Human, Component: React.createClass(Human) }
Фишка в том, что я экспортирую не только компоненту, но и «чистый» объект, из которого эта компонента создается, таким образом, когда мне надо использовать просто компоненту <Human/>, я беру поле Component из экспорта моего модуля:
var Human = require('human').Component;
А вот когда мне надо от моего модуля унаследовать, и тут начинается самое интересное, я использую поле Class:
var React = require('react'); var Parent = require('human').Class; var Programmer = {}; jQuery.extend(true, Programmer, Parent, { whoAreYou (){ return Parent.whoAreYou.apply(this) + " and a programmer";//вызов метода из родителя! } whatDoYouDo (){ //перезапись метода полностью return "I write code"; } drinkCoffee (){ //добавление нового метода console.log('*sip*'); } });
Естественно, этот модуль я тоже экспортирую согласно вышеописанной «конвенции»:
module.exports = { Class: Programmer, Component: React.createClass(Programmer) }
И теперь его можно использовать в приложении:
var Programmer = require('programmer').Component;
Ну, или наследовать/расширять дальше, например, в JuniorDeveloper.
И на этом все, это был мой коротенький пост про костыль для (псевдо)наследования в ReactJS. Успешной вам трудовой недели, господа!
ссылка на оригинал статьи http://habrahabr.ru/post/247347/
Добавить комментарий