使用 React.js 呈现 MDL 文本字段时出现问题

Issue while rendering MDL text field with React.js

我正在使用 Google 的 Material Design Lite Web 框架构建一个简单的登录页面,并使用 React.js 处理我的 UI 逻辑。

我遇到了一个非常奇怪的问题:当我在没有 React 的情况下渲染时,带有浮动标签的输入文本框工作得很好,但在通过 React 渲染时不起作用 class.

我的代码如下:

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。但它不起作用,预期的标签,从不 "floats" 意味着它留在文本框中。

当我复制相同的代码并将其粘贴到 HTML 时,效果很好。 (当然我改变了 classNamehtmlFor)。

可能是什么问题? 有什么帮助吗?这让我抓狂。

今天 Ember 遇到了类似的问题。问题是 MDL 的 JS 仅对 DOM 中已有的元素进行初始化。

您可以像这样使用 componentHandler 手动 'upgrade' 元素;

<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-class 中处理此升级。我用 Ember 中的一个组件解决了这个问题,该组件为我呈现文本字段/区域/单选按钮和复选框。

希望对您有所帮助!

尽管@Kevin E.'如果回答正确,我将 post 一个特定于 React 的答案。 根据官方 MDL 文档,

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

问题在于 React 的工作方式。显然,事实证明 React 不喜欢它的任何组件在它之外发生突变。

MDL 试图改变所有具有 类 mdl-js-* 的元素,以实现一些动态过渡和效果。此变更 必须 从 React 内部执行,否则将无法正常工作。

正确的方法是在 React 完成渲染 DOM 后立即调用 upgradeElement。因此调用必须放在 componentDidMountcomponentDidUpdate.

如果对一个个元素调用 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>
        );


    }
});