Проблема при рендеринге текстового поля MDL с помощью React.js

Я создаю простую страницу входа в систему, используя веб-фреймворк Google Material Design Lite и используя React.js для обработки логики моего пользовательского интерфейса.

У меня возникла очень странная проблема: текстовое поле ввода с плавающей меткой отлично работает, когда я визуализирую его без React, но не работает при визуализации через класс React.

Мой код выглядит так:

var Login = React.createClass({

    render: function(){
        return(
            <div className="mdl-grid">
            <div className="mdl-cell mdl-cell--2-col"></div>
            <div className="mdl-cell mdl-cell--8-col">

                <form>
                    <div className="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
                        <input className="mdl-textfield__input" type="text" id="sample3" />
                        <label className="mdl-textfield__label" htmlFor="sample3">Text...</label>
                    </div>
                </form>



            </div>
            </div>
        );


    }
});

Я убедился, что заменил class на className и for на htmlFor. Но это не работает, предполагаемая метка никогда не «плавает» означает, что она остается в текстовом поле.

Когда я копирую тот же код и просто вставляю его в HTML, он работает нормально. (Конечно, я меняю className и htmlFor).

В чем может быть проблема? Любая помощь? Это сводит меня с ума.


person Akshay Arora    schedule 03.10.2015    source источник


Ответы (2)


Хотя @Kevin E.' ответ правильный, я опубликую ответ, относящийся к React. Согласно официальным документам MDL,

... в случае динамического создания элементов DOM вам необходимо зарегистрировать новые элементы с помощью функции upgradeElement

Проблема в том, как работает React. Видимо, получается, что react не нравится, когда какие-то его компоненты мутируют вне его.

MDL пытается изменить все элементы с классами mdl-js-*, чтобы добиться некоторых динамических переходов и эффектов. Эта мутация должна выполняться внутри React, иначе ничего не будет работать.

Правильный способ сделать это — вызвать upgradeElement сразу после того, как React завершит рендеринг DOM. Следовательно, вызов должен быть помещен в componentDidMount и componentDidUpdate.

Если утомительно вызывать upgradeElement для элементов один за другим, используйте вместо этого upgradeDom. Он обновит все обновляемые элементы в DOM. Таким образом, окончательный код будет выглядеть примерно так:

var Login = React.createClass({


    loginRequested: function(){


    alert('login requested');

    },

    componentDidMount: function(){
        componentHandler.upgradeDom();

    },

    componentDidUpdate: function(){
        componentHandler.upgradeDom();
    },

    render: function(){
        return(
            <div>
            <div className="mdl-grid">
            <div className="mdl-cell mdl-cell--2-col"></div>

            <div className="mdl-cell mdl-cell--8-col">
            <div className="mdl-grid">
                <div className="mdl-cell mdl-cell--3-col"></div>
                <div className="mdl-cell mdl-cell--6-col">
                <form onSubmit={this.loginRequested}>
                    <div className="mdl-textfield mdl-js-textfield mdl-textfield--floating-label make-block">
                        <input className="mdl-textfield__input" type="text" id="sample3"/>
                        <label className="mdl-textfield__label" id="label-sample3" htmlFor="sample3">Username</label>
                    </div>
                    <div className="mdl-textfield mdl-js-textfield mdl-textfield--floating-label make-block">
                        <input className="mdl-textfield__input" type="text" id="sample3"/>
                        <label className="mdl-textfield__label" id="label-sample3" htmlFor="sample3">Password</label>
                    </div>
                    <input type="submit" value="Login" className="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent make-block"/>
                </form>
                </div>
            </div>


            </div>

            </div>
                </div>
        );


    }
});
person Akshay Arora    schedule 06.10.2015

Сегодня была аналогичная проблема с Ember. Проблема в том, что JS для MDL инициализирует только те элементы, которые уже находятся в DOM.

Вы можете вручную «обновлять» элементы с помощью componentHandler следующим образом;

<div id="container"/>
<script>
  var button = document.createElement('button');
  var textNode = document.createTextNode('Click Me!');
  button.appendChild(textNode);
  button.className = 'mdl-button mdl-js-button mdl-js-ripple-effect';
  componentHandler.upgradeElement(button);
  document.getElementById('container').appendChild(button);
</script>

Также см. http://www.getmdl.io/started/ (используйте MDL на динамических веб-сайтах). .

Я бы предложил обработать это обновление в вашем классе React. Я решил это с помощью компонента в Ember, который отображает для меня текстовые поля/области/переключатели и флажки.

Надеюсь, это поможет!

person Kevin E.    schedule 03.10.2015