Я не эксперт по самому механизму React, но идея его очень упрощенной версии, использующей некоторые концепции CS, может быть следующей:
Во-первых, React должен иметь список всех компонентов в вашем приложении, мы упростим его списком, но на самом деле это дерево:
const nodes = <>
<h1>My Counter</h1>
<Counter />
<div>
</>
Так что на этом этапе, если бы ваше приложение было плоским, DummyReactDOM.render(nodes)
создаст список этих node ":
nodes = [ h1, Counter, div ]
Ситуация становится сложной, когда вызывается useState
, и React будет сохранять какое-то состояние (запомненное состояние), например, узел Counter
может выглядеть так:
function Counter() {
[ counter, setCounter ] = useState(0);
}
Это добавит состояние к узлу:
node Counter = {
state : {
counter: 0
next : null
}
}
Теперь, что происходит, когда мы нажимаем на компонент и вызываем setCounter(counter + 1)
? A next состояние добавлено в очередь:
node Counter = {
state : {
counter : 0,
next : {
state : {
counter : 1, // <-- setCounter(counter + 1 happens)
next : null,
}
}
}
}
// firstState.next -> secondState.next -> null
Теперь планировщик - это главный ум узнать, какие компоненты необходимо перерисовать. Вот очень нереалистично c но простой для восприятия способ увидеть это:
while (true) {
// sleepForABit();
if (currentNode.state.next !== null && currentNode.state !== currentNode.state.next) {
currentNode.state = currentNode.state.next;
currentNode.component.render(); // or functionalComponent() call
}
currentNode = currentNode.next
}
Это простой случай если бы это был список узлов, но очевидно, что поскольку узел должен быть перерисован, React проверит его дочерние элементы. Важно отметить, что повторное рендеринг не так уж и дорого, дорогая часть - воссоздание DOM-узлов (и, в меньшей степени, их обновление), поэтому проверка дочерних узлов в большинстве случаев весьма производительна.
Надеюсь, это поможет!
В случае, если вам интересно, почему мы можем сделать setCounter(counter + 1)
, не имея counter = 0
всегда, React гарантирует, что узлы будут перерисованы при определенных событиях (onClick
как единое целое из многих).