最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Issue while rendering MDL text field with React.js - Stack Overflow

programmeradmin5浏览0评论

I am building a simple login page using Google's Material Design Lite web framework and using React.js to handle my UI logic.

I am experiencing a very strange issue: The input text box with floating label works perfectly fine when I render it without React, but doesn't work when rendered through a React class.

My code looks like:

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>
        );


    }
});

I have made sure I replace class with className and for with htmlFor. But it doesn't work, the intended label, never "floats" means it stays within the text box.

When I copy the same code and simply paste it in the HTML, it works fine. (Ofcourse I change the className and htmlFor).

What can be the issue? Any help? This is making me nuts.

I am building a simple login page using Google's Material Design Lite web framework and using React.js to handle my UI logic.

I am experiencing a very strange issue: The input text box with floating label works perfectly fine when I render it without React, but doesn't work when rendered through a React class.

My code looks like:

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>
        );


    }
});

I have made sure I replace class with className and for with htmlFor. But it doesn't work, the intended label, never "floats" means it stays within the text box.

When I copy the same code and simply paste it in the HTML, it works fine. (Ofcourse I change the className and htmlFor).

What can be the issue? Any help? This is making me nuts.

Share Improve this question asked Oct 3, 2015 at 4:14 Akshay AroraAkshay Arora 1,9451 gold badge16 silver badges31 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 9

Although @Kevin E.' s answer is correct, I will post an answer specific to React. According the the official MDL docs,

...in the case where you are creating DOM elements dynamically you need to register new elements using the upgradeElement function

The issue is with the way React works. Apparently, it turns out that react does not like when any of its ponents gets mutated outside of it.

MDL tries to mutate all elements with classes mdl-js-* so as to achieve some dynamic transitions and effects. This mutation must be performed from inside of React, else things won't work.

The proper way to do so is to call upgradeElement just after React has finished rendering the DOM. Hence the call must be placed in ponentDidMount and ponentDidUpdate.

If it is tedious to call upgradeElement on elements one by one, use upgradeDom instead. It will upgrade all upgradable elements in the DOM. So the final code would look something like this:

var Login = React.createClass({


    loginRequested: function(){


    alert('login requested');

    },

    ponentDidMount: function(){
        ponentHandler.upgradeDom();

    },

    ponentDidUpdate: function(){
        ponentHandler.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>
        );


    }
});

Had a simular issue today with Ember. The problem is the JS for MDL only initialises on elements already in the DOM.

You can manually 'upgrade' elements with the ponentHandler like this;

<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';
  ponentHandler.upgradeElement(button);
  document.getElementById('container').appendChild(button);
</script>

Also, see http://www.getmdl.io/started/ (Use MDL on dynamic websites).

What I'd suggest is handling this upgrade in your React-class. I solved it with a ponent in Ember that renders the textfields / areas / radio buttons and checkboxes for me.

Hopes this helps!

发布评论

评论列表(0)

  1. 暂无评论