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.