Pull to refresh

Comments 16

Не видел, но сейчас посмотрю. Я бы не называл это паттерном, мне кажется, это «костыль» до поры до времени, пока нам не завезут нормальные классы в ES6 или ES7.
в dojo ребята предложили довольно не плохой вариант наследования на миксинах с блекджеком и куртизанками, и мне порой не хватает механизма в той же джабе
А есть ли у ребят из dojo какая статья по этой теме? С удовольствием бы взглянул.
Честно говоря, не понимаю, почему было не сделать возможность обращаться к методам микшин, как, например, в ExtJS, для решения проблемы с дубликатами имен? См. docs-origin.sencha.com/extjs/4.2.3/#!/api/Ext.Class-cfg-mixins
Таким способом нельзя написать обобщенный mixin, а только расширять классы
Поясните, что такое «обобщенный mixin»? Если можно, с примером.
Ну вот например:
var Person = declare([], { say: function() { 
 console.log("hello"); });
var Man = declare([Person], { say: function() {
 this.inherited(arguments);
 console.log("i'm a man"); 
});
var Woman = declare([Person], { say: function() {
 this.inherited(arguments);
 console.log("i'm a woman"); 
});
var AwesomeMixin= declare([Person], { say: function() {
 this.inherited(arguments);
 console.log("And i'm awesome"); 
});
var AwesomeMan = declare([Man, AwesomeMixin]);
var AwesomeWoman = declare([Woman, AwesomeMixin]);
(new AwesomeMan()).say();
(new AwesomeWoman()).say();

я думаю понятно, что выдаст консоль
Признаюсь, без знания работы наследования в dojo, ответ был совсем не очевиден. Пришлось выполнять на jsfiddle. Не припомню случая, когда мне было необходимо именно такое поведение в повседневной работе.
Я бы сделал так:
module.exports = React.createClass(Human);
module.exports.Class = Human;

Теперь добраться до Human столь же просто, как и у вас — а вот до компонента добраться еще проще…
В текущей версии createClass и createElement работают с Factory, но в последней альфа версии (npm install react@0.13.0-alpha.1) они уже работают с нормальными конструкторами и можно использовать наследование.

//базовый класс компонента
var BaseComponent = React.createClass({
  render: function() {
    throw new Error('Component must implement render method')
  }
})

//обычное прототипное наследование
var MyComponent = function() {}
MyComponent.defaultProps = {name: 'MyComponent'}
MyComponent.prototype = Object.create(BaseComponent.prototype)

MyComponent.prototype.render = function() {
  return React.DOM.div(null, this.hello())
}
MyComponent.prototype.hello = function() {
  return 'Hello, my name is ' + this.props.name
}


Точно так же можно использовать любой способ наследования, например, ES6 классы, которые по сути просто синтаксический сахар, или любую библиотеку для наследования.

Отличие в том, что defaultProps нужно задавать статически.
И ещё одно отличие в том, что для своих специальных методов реакт определяет порядок вызовов и может объединять их возвращаемые значения, когда они встречаются нескольких миксинах. А в обычном наследовании каждый переопределяющий метод должен сам вызывать базовый метод и что-то делать с его результатами, если ему это надо. Поэтому при таком наследовании нельзя использовать существующие миксины.
С нетерпением ждем релиза.
Сорри, я-таки не понимаю в чем проблема. Я использую все тот же Browserfy + transform(es6ify) кторый замечательно поддерживает классы и беды не знаю. + sourcemaps, в чем минус?
Просто JSX из grunt-react уже поддерживает некоторые фишки ES6(но далеко не все), поэтому не возникало повода использовать сторонний препроцессор. Но спасибо за наводку, обязательно попробую. Правда, я использую grunt, но думаю не составит труда нагуглить es6 трансформер под grunt.
Какой смысл экспортировать компоненту? Для использования класса не нужна компонента, она нужна только в момент рендера, а там можно с помошью фабрики создать компоненту. Так что тут нужен только один экспорт — класса.

var IndexView = require('./templates/views/index'),
    UsersView = require('./templates/views/users'),
    UserView = require('./templates/views/user');

var IndexFactory = React.createFactory(IndexView),
    UsersFactory = React.createFactory(UsersView),
    UserFactory = React.createFactory(UserView);

//snip

        this.route(urls.user, 'user', function (user_id) {
            var user = users.get(user_id) || new User({'name': user_id});
            React.render(UserFactory({model: user}), document.getElementById('content'));
            user.fetch();
            console.log('hello user')
        });
Sign up to leave a comment.

Articles