添加表单时不变违规

时间:2015-08-06 14:47:58

标签: reactjs

[编辑]

Acutally,我认为我的问题是由于我在ASP.Net应用程序中的事实,它正在生成一个全局<form>元素。因此,浏览器会忽略尝试渲染的form,因为在html中禁止嵌套表单。

任何解决方法?

[/编辑]

我在反应世界中迈出了第一步,我面临着一个错误。

我已经写了一个小组件,应该显示链接和一个小表单来添加新组件。

我可以成功显示我的链接列表,但表单本身不起作用。

这是我的渲染方法:

render: function () {
    return (
    <div className="myLinks-new">
        <form onSubmit={this.handleSubmit} className="mylinks-newlinkform">
                    <input type="text" placeholder="Étiquette" ref="label" />
                    <input type="text" placeholder="Url cible" ref="target" />
                    <input type="text" placeholder="Mode d'ouverture" ref="openMode" />
                    <input type="submit" value="Ajouter" />
        </form>
    </div>)
    ;

认为错误部分是<form>节点。如果我删除它,没有错误。如果我离开它(只保留<div>节点,我进入js控制台:

  

Uncaught Error: Invariant Violation: findComponentRoot(..., .0.1.0): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID ``

如何解决?

奇怪的是,它会使另一个组件在结果中消失。表单本身显示在dom中,但不显示链接列表(实际上,第一个渲染过程有效,但我从ajax调用中获取状态并调用setState)。

我不知道这是否重要,但这是对我的组件的调用:

render: function () {

    return (<div className="myLinks">
            <MyLinksList links={this.state.data.Links} />
            <MyLinksAddLink onAddNewLink={this.handleNewLink} />
    </div>);
}

完整的代码是:

var MyLinksAddLink = React.createClass({
    handleSubmit: function (e) {
        e.preventDefault();
        var label = React.findDOMNode(this.refs.label).value.trim();
        var target = React.findDOMNode(this.refs.target).value.trim();
        var openMode = React.findDOMNode(this.refs.openMode).value.trim();

        this.props.onAddNewLink({ Label: label, Target: target, OpenMode: openMode });
        return;
    },

    render: function () {
        return (
        <div className="myLinks-new"><form onSubmit={this.handleSubmit} className="mylinks-newlinkform">
                        <input type="text" placeholder="Étiquette" ref="label" />
                        <input type="text" placeholder="Url cible" ref="target" />
                        <input type="text" placeholder="Mode d'ouverture" ref="openMode" />
                        <input type="submit" value="Ajouter" />
            </form>        </div>)
        ;
    }

});
var MyLinksListItem = React.createClass({
    render: function () {
        return (
               <li className="myLinks-list-item list-group-item">{this.props.link.Label}</li>
            );
    }

});
var MyLinksList = React.createClass({
    render: function () {
        var i = 0;
        var linkNodes = this.props.links.map(function (link) {
            i++;
            return (
                <MyLinksListItem key={i} link={link}/>
            );
        });
        return (
            <div className="myLinks-list-container">
                Here will be links
                    <ul className="myLinks-list list-group">
                        {linkNodes}
                    </ul>
            </div>);

    }
});

var MyLinks = React.createClass({
    getInitialState: function () {
        return {
            data: {
                Links: []
            }
        };
    },
    componentDidMount: function () {
        jQuery.ajax({
            url: this.props.url,
            dataType: 'json',
            cache: false,
            success: function (data) {
                this.setState({ data: data });
            }.bind(this),
            error: function (xhr, status, err) {
                console.error(this.props.url, status, err.toString());
            }.bind(this)
        });
    },
    handleNewLink: function (link) {
        var data = this.state.data;
        data.Links.push(link);
        this.setState({ data: data })
    },
    render: function () {

        return (<div className="myLinks">
                <MyLinksList links={this.state.data.Links} />
                <MyLinksAddLink onAddNewLink={this.handleNewLink} />
        </div>);
    }
});

在我页面的某处:

<script type='text/jsx'>React.render(<MyLinks url='/path/to/mydata' />, document.getElementById('somediv'));</script>

数据网址返回类似于:

的有效负载
{
  "Links": [
    {
      "Label": "MyLabel",
      "OpenMode": 1,
      "Target": "http:\\/\\/www.sosp.fr"
    },
    {
      "Label": "MyLabel2",
      "OpenMode": 4,
      "Target": "http:\\/\\/www.sosp.fr\\/2"
    },
    {
      "Label": "MyLabel3",
      "OpenMode": 0,
      "Target": "http:\\/\\/www.sosp.fr\\/3"
    }
  ]
}

[edit] 生成的DOM就是这个(来自Chrome开发工具):

<div class="myLinks" data-reactid=".0">
    <div class="myLinks-list-container" data-reactid=".0.0">
        <span data-reactid=".0.0.0">Here will be links</span>
        <ul class="myLinks-list list-group" data-reactid=".0.0.1"></ul>
    </div>
    <input type="text" placeholder="Étiquette" data-reactid=".0.1.0">
    <input type="text" placeholder="Url cible" data-reactid=".0.1.1">
    <input type="text" placeholder="Mode d'ouverture" data-reactid=".0.1.2">     
    <input type="submit" value="Ajouter" data-reactid=".0.1.3">
</div>

正如你所看到的,表格已经消失了。

1 个答案:

答案 0 :(得分:1)

如果某些内容更改了React控件之外的浏览器的DOM,那么您将收到Invariant Violation错误。正如您在生成的DOM输出的最后一个块中所示,正在尝试管理的<form>标记已被意外地从DOM中删除。

如错误消息中所述,This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to ... nesting tags like <form>

我无法从您发布的DOM部分中分辨出来,但如果您在编辑中说明了<form>个标记,那么浏览器将删除内部{{ 1}} tag和React会抛出错误。

您需要找到一种方法来阻止ASP.net框架创建<form>标记。