С чего начать изучение новой библиотеки или фрейморка? Сразу же найти статью на Хабре и с головой погрузиться в пучину практических примеров? Или сначала тщательно изучить официальную и неофициальную документацию, прежде чем перейти к практике? Именно между этими вопросами будет метаться ваше сознание, когда вы решите узнать, что же такое ReactJS. Чтобы желание учиться не умерло, как знаменитый ослик, обязательно загляните под капот.

Готовь сани летом а телегу зимой


Мало кто на перед задумывается о том, как готовое приложение будет работать на боевом сервере. Обычно эти вопросы решаются в самом конце, когда код уже написан, и пути назад нет. Именно поэтому прежде чем заняться изучением самой библиотеки, определитесь с вопросами компиляции кода вашего будушего творения. Варианта тут два. Для учебы, или скажем, демоверсии сайта, подойдет вариант компиляции на стороне клиента. Ничего делать не надо, все за вас сделает браузер, “на лету” так сказать. Но вот для готового продукта, я бы посоветовал настроить компиляцию на стороне сервера. Благо инструментов для этого предостаточно. Тут вам и Babel , и NodeJS или Webpack.

Детство, детство ты куда ушло


Ну вот, с вопросами компиляции разобрались. Перейдем к изучению? Нет, еще рано. React реализует модульный подход для построения приложений. Что это значит? Представьте себе конструктор. Не тот конструктор, что внутри класса, а простой детский конструктор. Точно так же, как из маленьких блоков в детстве вы строили свои шедевры, вы будете строить приложение из React компонентов. Так играть даже интересней, поскольку компоненты создаете тоже вы сами. Прелесть модульного подхода заключается в том, что создав и протестировав такой компонент один раз, вы легко можете использовать его и в других своих приложениях. Поэтому мой вам совет: создавайте отдельные файлы для каждого из них, а потом просто подключайте туда, куда надо. Вроде все просто, но это не совсем так. Приложение получиться пустым, мертвым, если его компоненты не будут “общаться” между собой. А это как раз и есть самое сложное и интересное.

Ну дайте же мне поработать!


Вижу, что ваше желание учиться тает на глазах. Поэтому открываем документацию и переходим от слов к делу. Все, что нам нужно для учебы, находиться на официальном сайте библиотеки. Правда информация структурирована плохо. Помочь вам не потеряться в этом хаосе — вот главная задача этой статьи.
Как вы уже поняли, основной задачей при разработке приложений на React, является разбивание страницы на блоки и создание компонентов, которые реализовывали бы функционал каждого из них.
Для начала создайте «статическую» версию вашего компонента. Очень рекомендую обратить внимание на JSX.

var LoginForm = React.createClass({

render: function() {
        
        return (
                <form id="login-form">
                    <input type="text" id="login" placeholder="login" />
                    <input type="password" id="password" placeholder="password" />
                    <button type="submit">Login</button>
                </form>
        )
}
});

React.render( <LoginForm />, document.getElementById('example'));

Оценили преимущества JSX синтаксиса? Тогда идем дальше. Добавим немного «интерактивности». Интерфейс компонента будет перерисовываться автоматически при изменении каких-либо данных внутри этого компонента. К ним относятся:

  • State (состояние) — набор данных, которые отражают состояние компонента в конкретный момент времени.
  • Props (свойства) — данные, передаваемые компоненту через атрибуты.

Поэтому все сводится к банальному изменению состояния или свойств в ответ на действия пользователя.

var LoginForm = React.createClass({
    getInitialState: function(){
        /* начальное состояние компонента */
        return { errorCode: 0, errorMessage: '', loginActions: [] };
    },

    doLogin: function(event) {
        event.preventDefault();
        
        var successLogin = (Math.random() >= 0.5) ? true : false;
        var actions = this.state.loginActions;

        if (!successLogin) {
            actions.push('Login failure');

            /* изменяем состояние компонента при возникновении ошибки */        
            this.setState({errorCode: 1, errorMessage: 'Error while login.', loginActions: actions});
        }
        else {
            actions.push('Login success');
            
            this.setState({errorCode: 0, errorMessage: '', loginActions: actions});
        }
    },

    render: function() {

        /* учитываем состояние компонента при отрисовке */
        var errorMessage = (this.state.errorCode > 0) ? this.state.errorMessage : '';
        var errorStyle = (this.state.errorCode > 0) ? {display: 'block'} : {display: 'none'};

        return (
            <div>
                <form id="login-form">
                    <div>
                        <input type="text" id="login" placeholder="login" />
                        <input type="password" id="password" placeholder="password" />
                    </div>
                    <div>
                        <button type="submit" onClick={this.doLogin}>Login</button>
                    </div>
                    <div style={errorStyle}>
                        <span style={{color: '#d9534f'}}> {errorMessage}</span>
                    </div>
                </form>
                
                <div className="actions-list">

                     /* передаем данные потомку через атрибут actions */
                    <ActionsList actions={this.state.loginActions} />
                </div>
            </div>
        )
    }
});

var ActionsList = React.createClass({

    render: function() {

        /* данные, полученые от родителя доступны через this.props */
        return (
            <ol>
                {
                    this.props.actions.map(function(action) {
                        return <li>{action}</li>;
                    })                
                }
            </ol>
        )
    }
});

React.render( <LoginForm />, document.getElementById('example'));

Как вы уже поняли, React значительно отличается от других библиотек. Поэтому нет ничего удивительного в том, что при работе с элементами формы тоже есть свои особенности, которые могут добавить вам изрядную долю седых волос на голове. Элементы формы делятся на два типа:

  • Не контролируемые — элементы, для которых свойство value не установлено.
  • Контролируемые — элементы, в которых установлено свойство value.

Давайте установим начальное значение для элементов ввода, и попробуем ввести что-нибуть:

<input type="text" id="login" placeholder="login" value=”admin” />

<input type="password" id="password" placeholder="password" value=”admpass” />

Как видим, у нас ничего не получилось. Теперь React «контролирует» эти элементы и нам нужно писать для них собственые обработчики изменений. Представляеке сколько это работы, писать функции-обработчики для каждого из контролируемых елементов? Мама не горюй! Но добрые дяденьки из Facebook не оставили нас в беде и добавили в React возможность использовать примеси (mixins). Да еще и несколько хороших дополнений (addons) подкинули.

var LoginForm = React.createClass({
    /* подключаем примеси */
    mixins: [React.addons.LinkedStateMixin],
    
    getInitialState: function(){
        return { errorCode: 0, errorMessage: '', loginActions: [], defaultLogin: 'admin', defaultPassword: 'password' };
    },

    doLogin: function(event) {
        event.preventDefault();
        
        var successLogin = (Math.random() >= 0.5) ? true : false;
        var actions = this.state.loginActions;

        if (!successLogin) {
            actions.push('Login failure');
        
            this.setState({errorCode: 1, errorMessage: 'Error while login.', loginActions: actions});
        }
        else {
            actions.push('Login success');
            
            this.setState({errorCode: 0, errorMessage: '', loginActions: actions});
        }
    },

    render: function() {
        var errorMessage = (this.state.errorCode > 0) ? this.state.errorMessage : '';
        var errorStyle = (this.state.errorCode > 0) ? {display: 'block'} : {display: 'none'};

        return (
            <div>
                <form id="login-form">
                    <div>
                        /* используем функцию из примеси и спецыальный атрибут valueLink */
                        <input type="text" ref="login" placeholder="login" valueLink={this.linkState('defaultLogin')} />
                        <input type="password" ref="password" placeholder="password" valueLink={this.linkState('defaultPassword')} />
                    </div>
                    <div>
                        <button type="submit" onClick={this.doLogin}>Login</button>
                    </div>
                    <div style={errorStyle}>
                        <span style={{color: '#d9534f'}}> {errorMessage}</span>
                    </div>
                </form>
                
                <div className="actions-list">
                    <ActionsList actions={this.state.loginActions} />
                </div>
            </div>
        )
    }
});

var ActionsList = React.createClass({

    render: function() {
        
        return (
            <ol>
                {
                    this.props.actions.map(function(action) {
                        return <li>{action}</li>;
                    })                
                }
            </ol>
        )
    }
});

React.render( <LoginForm />, document.getElementById('example'));

Если вы думаете, что «сюрпризов» больше не осталось, то очень сильно ошибаетесь. Вот вам задачка: как организовать двунаправленный обмен данными между компонентами? Ведь свойства передаются только в одном направлении — от отца к потомкам. А наоборот? Как потомок может влиять на данные своего родителя? Очень просто:

var LoginForm = React.createClass({
    mixins: [React.addons.LinkedStateMixin],
    
    getInitialState: function(){
        /* мы хотим, чтобы потомок мог изменять состояние родителя, в часности, очищать масив loginActions */
        return { errorCode: 0, errorMessage: '', loginActions: [], defaultLogin: 'admin', defaultPassword: 'password' };
    },

    clearActionList: function() {
          /* для этого  в родителе создаем функцию, которая очищает loginActions */
          this.setState({loginActions: []});
    },
    
    doLogin: function(event) {
        event.preventDefault();
        
        var successLogin = (Math.random() >= 0.5) ? true : false;
        var actions = this.state.loginActions;

        if (!successLogin) {
            actions.push('Login failure');
        
            this.setState({errorCode: 1, errorMessage: 'Error while login.', loginActions: actions});
        }
        else {
            actions.push('Login success');
            
            this.setState({errorCode: 0, errorMessage: '', loginActions: actions});
        }
    },

    render: function() {
        var errorMessage = (this.state.errorCode > 0) ? this.state.errorMessage : '';
        var errorStyle = (this.state.errorCode > 0) ? {display: 'block'} : {display: 'none'};

        return (
            <div>
                <form id="login-form">
                    <div>
                        <input type="text" ref="login" placeholder="login" valueLink={this.linkState('defaultLogin')} />
                        <input type="password" ref="password" placeholder="password" valueLink={this.linkState('defaultPassword')} />
                    </div>
                    <div>
                        <button type="submit" onClick={this.doLogin}>Login</button>
                    </div>
                    <div style={errorStyle}>
                        <span style={{color: '#d9534f'}}> {errorMessage}</span>
                    </div>
                </form>
                
                <div className="actions-list">
                     /* и передаем эту функцию потомку через атрибут, точно так же, как и данные */
                    <ActionsList actions={this.state.loginActions} clearActions={this.clearActionList} />
                </div>
            </div>
        )
    }
});

var ActionsList = React.createClass({

    render: function() {
        return (
            <div>
                /* здесь мы можем изменять состояния родителя, вызывая соответствующую функцию - this.props.clearActions */
                <button onClick={this.props.clearActions}> Clear list </button>
                <ol>
                    {
                        this.props.actions.map(function(action) {
                            return <li>{action}</li>;
                        })                
                    }
                </ol>
            </div>
        )
    }
});

React.render( <LoginForm />, document.getElementById('example'));

Делу время, потехе час!


Ну вот. Теперь действительно все. Первый этап пройден и я рад приветствовать вас в рядах новоиспеченных реакторов. Стоит ли ReactJS потраченного на него времени — каждый решает для себя. Пройдено только пол пути. Для кого-то эта дорога была легкой, для кого-то — не очень. Кто-то пойдет дальше, а кто-то остановиться. И я очень надеюсь, что моя статья будет хорошим подспорьем новичкам.

Комментарии (59)


  1. Drag13
    22.10.2015 11:56
    +7

    Вам удобно писать разметку в JS коде? Можно ли ее выносить в темплейты или как бороться с этим?


    1. kambur
      22.10.2015 12:00

      Вопрос хороший. Честно говоря, я пока над этим не задумывался.


      1. kambur
        22.10.2015 12:01

        Пока пробую JSX


        1. Drag13
          22.10.2015 12:08
          +2

          JSX, как я понимаю, представляет собой псевдо разметку, которую читает IDE.
          Т.е. проблема разделения вьюхи и Js остается. + Если IDE не поддерживает JSX то все совсем не удобно.
          Есть методы как с этим бороться?


          1. prog666
            22.10.2015 12:17

            Можно использовать SublimeText или Atom.io


          1. xamd
            22.10.2015 13:52

            Т.е. проблема разделения вьюхи и Js остается

            По каким-то причинам Вы считаете, что View — это не JS? React представляет собой идею функционального подхода к програмимрованию пользовательских интерфейсов, соответственно не имеет ничего общего с MVC и стараться «подбить» его к знакомой терминологии не имеет смысла.

            Если IDE не поддерживает JSX то все совсем не удобно.

            Ну, во-первых, уже, наверное, не осталось IDE, которые не поддерживают JSX, а во-вторых Вы всегда можете писать без JSX через React.DOM.div и т.п.


            1. Timmmm
              22.10.2015 17:46

              Что бы вы не говорили, но единственная задача view это отрисовка. Нельзя мешать представление с моделью.


              1. xamd
                22.10.2015 17:53
                +2

                Конечно, React вообще не должен ничего знать о данных, которые поступают в его компоненты! Поэтому и появился flux — чтобы решить проблему работы с данными и коммуникацией между компонентами. Довольно тяжело сейчас говорить о React без упоминания Flux.


              1. batmandarkside
                23.10.2015 10:20
                +2

                Раньше как и вы мыслил. Пришло время адаптироваться. И я понял что так намного удобнее. Нет больше трёх разных сущностей как html css js. Есть одна — веб компонент. Для этого мы и держим все в одной папке, составляющие компонента. Держать разметку в js отличная идея, удобно. Как правило разметка не большая. Если у вас вёрстки в компоненте на целую страницу, значит что то пошло не так !)


                1. Timmmm
                  23.10.2015 10:43

                  Не буду с вами спорить, если вам удобно… Но архитектурно это не правильно, вас поставили в рамки которые противоречат здравому смыслу. Все это выглядит как костыль. Напоминает сервлеты от которых отказались, в плане верстки, уже очень давно.


                  1. batmandarkside
                    23.10.2015 11:25

                    Яснопонятно


                1. FaNtAsY
                  27.10.2015 17:33

                  Мысль про веб компонент отличная — в одной папке html, css, js. Я её поддерживаю.
                  Но хотелось бы держать все три элемента в трёх разных файлах: *.html, *.css, *.js соответственно.


          1. kambur
            22.10.2015 14:37
            +1

            Я не уверен, что в случае с React есть необходимость разделять код от от представления.
            Но тут все зависит от индивидуальных предпочтений.
            Если разработчик создает много компонентов и помещает все это в один файл, получается каша. Тогда есть смысл как-то навести порядок и разделить js от html
            Но я сторонник модульного подхода к разработке. Один компонент — один маленький блок html + код реализации логики.


          1. kambur
            22.10.2015 14:40

            По большому счету можно вобще отказаться от html в компонентах и писать все на чистом React.
            В таком случае ваши компоненты будут универсальными.


    1. kambur
      22.10.2015 12:05

      Я думаю, что разработчикам в будущем не помешает
      1. Добавить поддержку темплейтов
      2. Улучшить работу со свойствами (скажем придумать объект parent через который потомок может изменять состояние родителя)


      1. xamd
        22.10.2015 13:45
        +3

        1. О каких темплейтах Вы говорите?
        2. Никакого two-way data-binding. Все свойства передаются от родителя к потомку и никак иначе. А вообще, для работы с данными в React существует множество библиотек (например, redux)


        1. DeLaVega
          23.10.2015 11:41

          По второму пункту, так на секундочку — https://www.npmjs.com/package/react-binding


          1. xamd
            25.10.2015 21:59

            «Так на секундочку» — 115 скачек за последний месяц + 14 звёзд на GH и 2 issue за 5 месяцев. Я бы не полагался на подобную библиотеку при проектировании приложения, особенно если она идёт вразрез оф. идеологии.

            Видимо, я не совсем ясно выразился: разумеется, сделать можно всё что угодно — это js, в конце концов. Вы так же можете использовать родной хак: facebook.github.io/react/docs/two-way-binding-helpers.html, однако даже на этой странице написано, что React спроектирован как one-way data flow система.


      1. i360u
        22.10.2015 16:30

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


        1. xamd
          25.10.2015 22:01
          +1

          Это называется «dumb components» и в React 0.14 реализуется с помощью обычных функций:

          // A functional component using an ES2015 (ES6) arrow function:
          var Aquarium = (props) => {
            var fish = getFish(props.species);
            return <Tank>{fish}</Tank>;
          };
          
          // Or with destructuring and an implicit return, simply:
          var Aquarium = ({species}) => (
            <Tank>
              {getFish(species)}
            </Tank>
          );
          
          // Then use: <Aquarium species="rainbowfish" />
          

          Взято из пресс-релиза 0.14


          1. i360u
            26.10.2015 08:52

            Dumb component, насколько я понимаю, это просто обертка в виде кастомного тега, содержащая верстку и не содержащая внутренней логики. Что-то типа:

            <div>{this.props.children}</div>
            
            Компоненты имеет смысл делать только если они переиспользуются, а внутри компонента шаблон вывода элемента можно сделать кучей разных способов.


            1. xamd
              26.10.2015 11:12

              Основная идея, «пропитывающая» реакт — композиция элементов. Т.е. «шаблон вывода» в Вашем понимании составляется из маленьких dumb components, которые при аггрегации образуют то, что Вам нужно.

              Разумеется, где-то вверху будет находится smart component, который будет оркестрировать весь процесс: забирать данные из какого-нибудь хранилища (будь то что-то самописное, redux store или что либо ещё) и передавать эти данные в ваши dumb components и, возможно, содержать логику а-ля «если количество записей больше нуля, показывать dumb component со списком записей, в противном случае показывать заглушку с сообщением об отсутствии записей». По факту весь реакт — это один большой шаблон, если так посмотреть :)


              1. auine
                26.10.2015 11:17

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


    1. prog666
      22.10.2015 12:06
      +1

      Это такая «фишка» реакта, мне вначале казалось неудобным, но быстро привыкаешь и начинаешь даже любить эту схему. А вообще можно использовать jade шаблоны. Посмотрите на react-jade.


      1. Drag13
        22.10.2015 12:09
        +9

        Любить разметку в JS? :D


        1. prog666
          22.10.2015 12:11

          Выходит что код разделен на маленькие модули всегда, и очень часто нужно менять разметку вместе с JS, в данном случае проще ничего не забыть ибо все на виду


          1. Drag13
            22.10.2015 12:16
            +2

            Возможно это дело привычки.


        1. CJay
          22.10.2015 13:06
          +6

          На мой взгляд, вычленять разметку из JSX не стоит. Почему?
          1) Метод render у меня ещё ни разу не оказывался больше высоты экрана (обычно вообще строк 12-20).
          2) В шаблоне логики вообще нет, никаких условных конструкций или циклов. Вся логика реализована выше в самом JS.
          3) Желательно видеть, какие ноды какими ref я подписал, или какой метод вызвать при каком-то событии. Значит всё должно быть под рукой, а не переключаться между двумя файлами.

          Причины за «выделение шаблона в отдельный файл» мне в голову не приходят. Станет хуже.

          P.S.
          По началу тоже думал, что html в JS — это какая-то дикость. Но изменил свою точку зрения. По поводу поддержки IDE — работал с jsx в Sublime без какой либо поддержки React, подсветки синтаксиса JS вполне хватало.


          1. Drag13
            22.10.2015 13:11

            Спасибо за подробный ответ.


          1. JCHouse
            22.10.2015 23:50

            Согласен, то что с первого взгляда кажется дикостью, после месяца подсаживает на именно такой стиль написания кода. Все что можно вынести в другой компонент выносится и html не выглядит грамоздко.


        1. serf
          22.10.2015 18:19
          -3

          Может быть человек давно начинал с PHP и с тех пор полюбил подход мешать код и разметку вместе. Фейсбук вот тоже с PHP дружит, вот и сделали в своем родном стиле.


    1. arvitaly
      22.10.2015 12:12

      Выносить можно, так как по сути в итоге там обычное JS-выражение. Т.е. его можно записывать в переменную, экспортировать из модуля и т.д. На практике, это обычно не нужно, так как если HTML-кода становится очень много, значит компонент плохой, а небольшое количество HTML-кода в методе render не мешает.

      Так же в TypeScript запилили поддержку JSX (TSX) с проверкой типов, компиляцией и подсветкой. Пока сыровато, но обещает быть очень вкусно.

      В целом, другого пути, кроме смешения JS и HTML, особо и нет, выдумывать тонны селекторов и писать отдельно обработчики событий больше нет желания, спрашивается, с чего начинали…


    1. Igogo2012
      22.10.2015 12:14

      Во перых это не JS, а JSX
      И по сути react это и есть умный темплейтовый движок, так что любые файлы с расширением .jsx в проекте написанном на реакте по своей сути являются темплейтами, а уже как фреймворк отвечающий за логику можно брать до пустим backbone.


      1. Drag13
        22.10.2015 12:17

        Я могу ошибаться (тогда поправьте), я думал что JSX это псевдо-разметка, а JS это клей который обеспечивает функциональность компоненты. И имел ввиду смешение первого и второго.


        1. Igogo2012
          22.10.2015 12:26
          +1

          JUST THE UI
          Lots of people use React as the V in MVC. Since React makes no assumptions about the rest of your technology stack, it's easy to try it out on a small feature in an existing project.


          Из офф сайта реакта, даже разработчики утверждают что большенство людей используют его как View в MVС.
          По всей своей сути react это как бы описание UI объекта.
          И для того что бы не смешивать реальный JS и не тулить туда еще и разметку, разработчиками был выбран альтернативный формат .jsx который и решает данную задачу.
          То есть в любом случае в Ваших jsx файлах будет как минимум не много js-подобного кода и xml-разметка (по тому что это точно не html).
          Но логику и обработку данных все же лучше выносить в контроллеры и модельки Вашего приложения, дабы View оставался максимально чистым.


    1. xamd
      22.10.2015 13:41

      JSX используется в качестве препроцессора для улучшения «читабельности» кода. «Под капотом» оно транслируется в ES5-совместимый формат, т.е.

      render() {
        return <div>hello</div>;
      }
      


      будет транслирован в

      render() {
        return React.DOM.div(null, 'hello');
      }
      


      Разумеется, вы можете использовать вторую версию без каких-либо препроцессоров. Об это подробнее на оф. сайте. Так же, в версии 0.14 работа с DOM вынесена в отдельную библиотеку react-dom.


    1. Delphinum
      22.10.2015 14:07

      Попробуйте RequireJS с плагином text.


    1. Sunify
      22.10.2015 14:11

      По факту, это не то чтобы разметка. Это язык описания дерева UI, т.е. он включает в себя, помимо тегов, вызовы компонент. А в случае с каким-нибудь React Native, там вообще нет привычных тегов.


    1. timramone
      22.10.2015 23:11
      +2

      Не нужно выносить разметку. Она связана с логикой приложения, и это не coupling, это cohesion. Компонент — это логика и представление. Тут SRP не по принципу «ты определяешь представление (как будет выглядеть какой-то элемент)» и «ты определяешь логику (как взаимодействовать с конкретным элементом)», а по принципу «ты инкапсулированный компонент, в тебе представление и логика его отображения».
      Тут правда есть нюанс с тем, как верстальщика с этим работать заставить. У нас процесс построен, что верстальщик концептуально верстает элементы управления, а мы уже из этой вёрстки создаём компоненты, так что у нас нет проблемы.
      На эту тему есть совершенно прекрасный доклад Александра Соловьева Как писать UI без боли. Вообще у него совершенно потрясающие видео на YouTube, очень советую и другие посмотреть :)


  1. prog666
    22.10.2015 12:00
    +1

    Если уж все равно приходится использовать browserify или webpack то можно было бы писать на es2015/es6, babel (babelify) отлично понимает jsx и в самой документации реакта есть примеры как можно использовать нативные классы в создании компонентов. Если интересно могу показать примеры gulpfile для сборки.


    1. kambur
      22.10.2015 12:06

      Это было бы здорово



    1. VasilioRuzanni
      22.10.2015 14:36
      +1

      Добавлю, что Babel не только понимает JSX, но и сама команда React'а даже отказалась от своих наработок и рекомендует использовать Babel для трансформации.


    1. timramone
      22.10.2015 23:12

      Или txs ;)


  1. aTwice
    22.10.2015 12:53
    +3

    Как потомок может влиять на данные своего родителя? Очень просто:

    и далее простыня кода без комментариев.
    Вы бы хоть полужирным выделили изменения по отношению к предыдущей простыне.


    1. kambur
      22.10.2015 15:03

      Вы абсолютно правы. Приношу свои извинения и бегу писать коменты.


  1. andreysmind
    22.10.2015 13:16

    Вот вам задачка: как организовать двунаправленный обмен данными между компонентами?

    Может лучше сразу к Flux привыкать?
    Вроде даже в Angular 2 от двунаправленного обменами данных решили отказаться?


    1. VasilioRuzanni
      22.10.2015 14:55

      И в Angular 2, и в Ember 2 тоже (и там, и там — плотно советуясь с командой React), и на Angular 1 тоже в итоге для больших приложений получается удобнее писать (субъективно), когда есть явная передача данных «туда» и «обратно».

      Однако, часто бывает удобен и 2-way-binding, но надо понимать, когда его лучше использовать (в Aurelia он хорошо сделан и лишен недостатков оного в Angular 1) — тут создатели разных фреймворков вроде как сошлись во мнении, что правильный 2-way-binding — это сахар над one-way-binding для отдельных случаев (именно такой подход используется в ng2 с его жуткими "([...])" скобками в шаблонах и похожий в Aurelia с его «адаптивными байндингами»).


    1. kambur
      22.10.2015 20:20

      Flux — я за!!!


  1. stardust_kid
    22.10.2015 13:17
    +7

    Эта статья — отличный пример того, как не надо писать статьи. В начале 3 абзаца переливания из пустого в порожнее.

    Перейдем к изучению? Нет, еще рано. React реализует модульный подход для построения приложений. Что это значит? Представьте себе конструктор. Не тот конструктор, что внутри класса, а простой детский конструктор.

    Вы вообще свой текст перечитывали? Нет, перечитывали. Может перечитаете? Нет, еще рано. Постойте. Нет, читайте. А, блин, уже поздно, Евгений Ваганыч недоволен.
    Потом несколько кусков кода без комментариев. Думаете, в интернете мало примеров кода на React, вся надежда на вас?
    Тем читателям, кто осваивает React с нуля советую начать с официальной документации, там все понятно и подробно.


    1. kambur
      22.10.2015 15:51

      Тут я с вами абсолютно не согласен. Для вас, как опытного программиста, статья действительно может показаться убожеством. Просто она предназначена не для вас. Я не преследовал цель создать первоклассный туториал, их и так как листьев на деревьях. А что делать человеку, который только, только делает первые шаги по пути фронт-енд разработки? Кто ему подскажет, кто направит?
      Меня сильно раздражают напыщенные индюки вроде вас, которые только и умеют критиковать. Нет чтобы помочь, подсказать и сделать статью лучше. Ведь конечная цель — помощь людям!


      1. stardust_kid
        22.10.2015 16:36
        +2

        Это спорно, кто из нас двоих больше подходит под определение «напыщенного индюка». В любом случае, словоблудие и малое количество информации вряд ли помогут начинающему программисту. Ваша статья не подсказывает и не направляет.


        1. kambur
          22.10.2015 16:51

          Поживем — увидим.
          Как говорил Максим Горький:
          … Мудрость жизни всегда глубже и обширнее мудрости людей.



  1. n0ne
    23.10.2015 12:46

    Может кто-то посоветует приличные компаненты для работы с формами? Валидация, локализация, кастомизация и т.п.
    А так же кучу-кучу всяких компонентов для этих форм.
    Может кому-то удалось локализировать DatePicker из Material UI?


    1. mordaha
      26.10.2015 08:48

      Все что есть все тут github.com/enaqx/awesome-react


      1. n0ne
        26.10.2015 11:45

        Спасибо, про это я знаю…
        Как по мне — беда-беда…


  1. mordaha
    23.10.2015 12:57
    +3

    Обзор двух-летней давности )
    На реакте сейчас пишут как-то вот так teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html


    1. xamd
      26.10.2015 11:16

      Отличная статья, кстати говоря.