简体   繁体   中英

Custom Render function in JSX - How to handle fragments

I'm trying to use JSX by itself (without React) to render some dynamic content, with a custom createElement function. I'm using webpack with the following setting: { "pragma": "createElement", "pragmaFrag": "'fragment'" } for @babel/plugin-transform-react-jsx .

here is my custom renderer code:

function createElement(tagName, attrs = {}, ...children) {
    let el = document.createElement(tagName);

    if (attrs) {
        for (let [ key, val ] of Object.entries(attrs)) {
            if (key === 'className') {
                el.className = val;
            } else {
                el.setAttribute(key, val);
            }
        }
    }

    for (let child of children) {
        if (Array.isArray(child)) el.append(...child);
        else el.append(child);
    }

    return el;
}

I'm curious how i could handle fragment elements ( <>content</> ) in this function. By googling, I've found people adding the following:

function createElement() {
  // ...
  if (tagName === 'fragment') return children;
  // ...
  return el;
}

but this just returns the string "[object HTMLLIElement]" , which makes since to me since it seems that createElement must return one node element and not a NodeList or array of some sort.

Is there a way to easily implement fragments in my createElement function? Thanks

edit:

Using TJ's answer below, i was able to fix the problem by adding the following line to make use of DocumentFragment :

    let el = tagName === 'fragment' ? new DocumentFragment() : document.createElement(tagName);

It's pretty much up to you how you handle it, since you also (presumably) wrote the code that uses what your createElement returns (eg, putting those things in the DOM — your equivalent of ReactDOM.render or similar). You could return an array, or a document fragment , or your own custom container. Whatever it is, your code that takes these and puts them in the DOM just has to check for it and handle it appropriately.

I should note that createElement doesn't generally create DOM elements directly. It creates objects (typically) that have the information to create elements, but not actual elements. One reason for that is that you don't always turn those objects into DOM elements; if you're updating rather than mounting, you're often updating your existing DOM elements based on updated information in the objects. Of course, you can do it differently, there's no "wrong" here. :-) I mention it because knowing that may help you with your fragment issue.

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