Прежде всего, под «повторным рендерингом» здесь подразумевается либо
- , вызывается метод
render()
любого компонента класса, ИЛИ - функция вызывается компонент функции.
Давайте назовем элемент в реальном DOM, изменив «refre sh», чтобы отличить guish его от «re-render».
Является ли правило «повторного рендеринга» простым, как:
Когда любое состояние компонента изменяется, то компонент и все поддерево, находящееся внизу этого компонента, повторно визуализируется
и все? Например:
function A() {
console.log("Component A re-render");
return <div>Component A says Hello World</div>;
}
function App() {
const [counter, setCounter] = React.useState(0);
console.log("Component App re-render");
function increaseCount() {
setCounter(c => c + 1);
}
return (
<div>
{counter}
<button onClick={increaseCount} >Increment</button>
<A />
</div>
)
}
ReactDOM.render(<App />, document.querySelector("#root"));
<script src="https://unpkg.com/react@16.12.0/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>
Компонент А очень прост: он даже не берет никаких реквизитов и просто выводит текст c, но он все равно вызывается каждый раз ( глядя на вывод console.log()
).
Но даже если он «перерисован», фактический элемент DOM не «обновляется», как видно из элемента проверки Google Chrome, что Элемент DOM не мигает для компонента A, а мигает только для номера счетчика.
Так вот как это работает?
- Всякий раз, когда изменяется любое состояние компонента, это Компонент и все поддерево будут «перерисованы».
- Но ReactJS будет «согласовывать» содержимое «Виртуального DOM», созданного с использованием этих JSX, с содержимым фактического DOM, и если содержимое отличается, "refre sh фактического DOM".
Но, сказав это, кажется, что ReactJS на самом деле не согласуется с фактическим DOM, но согласовывается, вероятно, с «предыдущий виртуальный DOM». Почему? Потому что, если я использую setTimeout()
, чтобы через 3 секунды изменить фактическое DOM компонента A на другое содержимое, и нажму кнопку, ReactJS не изменит содержимое компонента A обратно на «Hello World». Пример:
function A() {
console.log("Component A re-render");
return <div id="foo">Component A says Hello World</div>;
}
function App() {
const [counter, setCounter] = React.useState(0);
console.log("Component App re-render");
function increaseCount() {
setCounter(c => c + 1);
}
return (
<div>
{counter}
<button onClick={increaseCount} >Increment</button>
<A />
</div>
)
}
ReactDOM.render(<App />, document.querySelector("#root"));
setTimeout(function() {
document.querySelector("#foo").innerText = "hi"
}, 3000);
<script src="https://unpkg.com/react@16.12.0/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>