NodeView contentDOM is wrapping children with HTMLElement

I have a schema like below:

<figure>
  <figcontent> <--- a div tag
    <img>
    <figcaption>
  </figcontent>
<figure>

And I have a NodeView for figure node. I want contentDOM to manage what should be inside of figure, which is figcontent and img, figcaption nested. According to my understandings, this.dom is the figure node, and this.contentDOM is the figcontent that wraps img and figcaption. However, the code below produces anothor html element that wraps the original figcontent.

class FigureNodeView {
  constructor(node, view, getPos) {
    this.node = node
    this.view = view
    this.getPos = getPos

    this.dom = document.createElement('figure')

    this.contentDOM = document.createElement('span')

    this.dom.append(this.contentDOM)
  }
the outcome:

<figure>
  <span> <--- unnecessary wrapper is created
    <figcontent>
      <img>
      <figcaption>
    </figcontent>
  </span>
<figure>

below is my schema.

  figure: {
    content: 'figcontent',
    group: 'block',
    attrs: {
      style: {
        default: 'display:flex;justify-content:center;',
      },
    },
    marks: '',
    draggable: true,
    selectable: true,
    parseDOM: [{tag: 'figure'}],
    toDOM(node) {
      return ['figure', {style: 'display:flex;justify-content:center;'}, 0]
    },
  },

  figcontent: {
    content: 'image figcaption',
    attrs: {
      class: {default: MEDISTREAM_EDITOR_CLASS + '__figcontent'},
    },
    group: 'figure',
    marks: '',
    selectable: false,
    parseDOM: [{tag: 'div'}],
    toDOM: node => ['div', {class: node.attrs.class}, 0],
  },

  figcaption: {
    content: 'inline*',
    attrs: {
      class: {default: MEDISTREAM_EDITOR_CLASS + '__figcaption'},
    },
    group: 'figcontent',
    marks: 'strong link',
    parseDOM: [{tag: 'figcaption'}],
    toDOM(node) {
      return ['figcaption', {class: node.attrs.class}, 0]
    },
  },

  image: {
    attrs: {
      src: {
        default:
          'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII',
      },
      alt: {default: null},
      title: {default: null},
      width: {default: '200px'},
      height: {default: 'auto'},
      class: {default: MEDISTREAM_EDITOR_CLASS + '__img'},
    },
    group: 'figcontent',
    draggable: false,
    selectable: false,
    toDOM(node) {
      const {src, alt, title, width, height} = node.attrs
      return [
        'img',
        {
          src,
          alt,
          title,
          width,
          height,
          class: node.attrs.class,
        },
      ]
    },
    parseDOM: [
      {
        tag: 'img[src]',
        /**
         * @param {HTMLElement} dom
         */
        getAttrs: dom => ({
          src: dom.getAttribute('src'),
          title: dom.getAttribute('title'),
          alt: dom.getAttribute('alt'),
          width: dom.getAttribute('width'),
          height: dom.getAttribute('height'),
        }),
      },
    ],
  },

Solved with this.contentDOM = this.dom and I removed this.dom.append(this.contentDOM).