Была поставлена задача реализовать свою JSX factory. Из документации React мы знаем, что JSX транспилируется в вызов функции React.createElement(type,props,child)
, где child выражено rest параметром (передает через запятую массив потомков). Но каким образом сравниваются текущее и новое древо? Ведь это абсолютно обособленные объекты.
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div>
<p>It's</p>
<p>OK</p>
</div>
);
}
}
export default App;
Кроме того, что является критерием невозможности частичного рендеринга без поля key в перечислении? Мы же можем поставить два блока p подряд и ничего страшного не произойдет...
При получении child происходит "уплощение массива" - для избавления от включений map(), которые возвращают массив. Далее сравнение элементов древ можно осуществить следующим алгоритмом:
Если совпали, идем к родителям
Реализация данного алгоритма в псевдо-коде:
bool Element::equals(
const Element* a,
const Element* b,
bool recursive=true
) {
if (a->key!=b->key) {
return false;
} else if (a->type!=b->type) {
return false;
} else if (recursive) {
const Element* parent1 = a;
const Element* parent2 = b;
while(true) {
parent1 = parent1->parent;
parent2 = parent2->parent;
if (parent1==nullptr&&parent2==nullptr) {
return true;
} else if (parent1==nullptr&&parent2!=nullptr) {
return false;
} else if (parent1!=nullptr&&parent2==nullptr) {
return false;
} else if (!equals(parent1, parent2, false)) {
return false;
} else {
continue;
}
}
} else {
return true;
}
}
Критерием невозможности частичного рендеринга является наличие трех и более (в строковом представлении древа потомков) эквивалентных элементов подряд, так как при попытке определить изменения будут удалены последние, а не изменившиеся.
Более подробно об этом явлении можно прочитать в этом репозитории.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Когда пользователь желает распечатать страницу, в зависимости от того какую ориентацию, в открывшемся окне, он выберет (портретная/альбомная),...
Хотелось бы, чтобы при нажатии на кнопку прошлый клик с переменной 'hi' удалялсяНо почему-то этого не происходит
Я обучаюсь сейчас reduxЗадача стоит в том, чтобы переписать виджет комментариев с одного react на redux