简体   繁体   中英

How to rebuild a existing Dom in reactjs?

I am currently trying to get reactJS working with the following Setup:

I am getting a xml-DOM from the Server. Its a server side rendered "custom" DOM, which normaly gets consumed by another client (not html, but java) which renders components.

<row id="a">
    <label id="aa" width="140" text="Title" />
    <field id="ab" bgpaint="" width="200" text="" enabled="true" />
</row>

I defined some ReactComponents with React.createClass(). So I have a Label, a Field and a Row (div).

Currently I cannot work out a way to render the Components of the xml-DOM with react. I am going trough the xml-DOM and got the snippet from above. If I find a "row" shell I call React.createElement(Row, {}, ?)? But I i dont know what children will be to fill the '?' before I go deeper into the xml-DOM. If I walk through the xml-DOM until I got a "endNode" with no children, how can i create the react elements from bottom to top? Do I have to create a super String and somehow call it as javascript.

Is there a way to create a Row, and afterwads add the children? Do I have to use the components props? Something like:

//<row> found
var newRow = React.createElement(Row, {}, ?);
...
//found the label in the row
var newLabel = React.createElement(Label, {}, "Title");
newRow.add(newLabel);

I can hardly come to a solution - is it possible to do with react? Or am I trying to do something which react is not made for? Probably I do not understand the child concept totally. Or maybe its not really a react-Problem itself...

Any hints for me?

greetz

Create the children array before you call createElement. For example ( jsfiddle ):

function pascalize(str) {
    return str.split("-").map(function(name) {
        return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
    }).join("");
}

function attrsToProps(attrs) {
    var obj = {};
    for (var i = 0; i < attrs.length; ++i) {
        obj[attrs[i].nodeName] = attrs[i].value;
    }
    return obj;
}

function toReact(node, components) {
    if (node.nodeType === 1) {
        var children = [].map.call(node.childNodes, function(child) {
            return toReact(child, components);
        });
        return React.createElement(components[pascalize(node.nodeName)],
                                    attrsToProps(node.attributes),
                                    children);
    } else if (node.nodeType === 3) {
        return (node.nodeValue + "").trim();
    }
    return "";
}

function xmlToReactComponents(xmlDom, components) {
    if (xmlDom && xmlDom.documentElement) {
        return React.createElement("div", [], [].map.call(xmlDom.documentElement.childNodes, function(child) {
            return toReact(child, components);
        }));
    }
}

The usage in jsfiddle is:

var xml = document.querySelector("#xml").innerHTML;
var parser = new DOMParser();
var dom = parser.parseFromString(xml, "text/xml");

var defaultClass = {
    render: function() {
        return React.createElement("div", {}, "id: " + this.props.id, this.props.children);
    }  
};

var components = {
    Row: React.createClass(defaultClass),
    Label: React.createClass(defaultClass),
    Field: React.createClass(defaultClass)
}
var result = xmlToReactComponents(dom, components);
React.render(result, document.body);

You need to pass all the components the xml could create in the object otherwise whole thing fails

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM