Piszemy funkcję, która rozwija VDOM. Chodzi o funkcję, która wytwarza VDOM (z jakichś elementów JSX), który potem można przekazać do renderowania, mountowania, diffowania i updatowania.

Jak się o tym gada, to jest trudne i niezrozumiałe. Jak się to robi (pod warunkiem, że małe kroczki) to wszystko jest jasne. Zatem:

function createElement_v5(type, attributes = {}, children = []){
    return {
        type: type,
        children: children,
        props: Object.assign({children: children}, attributes)
    }
}

let v5 = createElement_v5("h1", {textContent: "hello world"}, children = ["text", "text2"]);

console.log(v5);

// Object { 
//     type: "h1", 
//     children: Array [ "text", "text2" ], 
//     props: { 
//         children: Array [ "text", "text2"],
//         textContent: "hello world"
//     }
// }

Taki to nasz VDOM. Obiekt ma typ, tablicę dzieci, oraz propsy, w których pod children są dzieci a reszta to inne atrybuty.

Krok następny:

function createElement_v6(type, attributes={}, children=[]){
    const childElements = [...children].map(
        child =>
            child instanceof Object
                ? child
                : createElement_v6("li", {
                    textContent: child
                }) 
              );

            return {
                    type,
                    children: childElements,
                    props: Object.assign({ children: childElements }, attributes)
            }
}

Rozjaśni się to po dwóch przykładach:

let v6 = createElement_v6("ul", {class: "my-list"}, children = [
    "PHP", 
    "JAVASCRIPT",
    'C#'
   ]
);

console.log(v6);


// Object { 
//     type: "ul",
//      children: (3) [
//         0: Object { 
//             type: "li", 
//             children: [], 
//             props: Object { children: [], textContent: "PHP" }
//          }
// ​​
//         1: Object { type: "li", children: [], props: {…} }
// ​​
//         2: Object { type: "li", children: [], props: {…} }
//      ], 
//      props: {
//         children: Array(3) [ {…}, {…}, {…} ],
// ​​        class: "my-list"
//      } }

Ok, teraz zobaczymy jak reaguje na obiekt:

let v6_2 = createElement_v6("ul", {class: "my-list"}, children = [
    "PHP", 
    "JAVASCRIPT",
     {
        type: "li",
        children: [],
        props: {
            children: [],
            textContent: "PHP"
        }
     }
   ]
);

console.log(v6_2);

// Object { 
//     type: "ul",
//      children: (3) [
//         0: Object { 
//             type: "li", 
//             children: [], 
//             props: Object { children: [], textContent: "PHP" }
//          }
// ​​
//         1: Object { type: "li", children: [], props: {…} }
// ​​
//         2: Object { type: "li", children: [], props: {…} }
//      ], 
//      props: {
//         children: Array(3) [ {…}, {…}, {…} ],
// ​​        class: "my-list"
//      } }

Docelowo tam ma nie być li, tylko „text”. Chodzi o to, aby umieć wytwarzać textNodes, które mają tylko typ tekst i textContent. Więcej w następnej lekcji.