バーチャルDOM(バーチャルドーム)


はんのう
反応層は反応層の「UIを表現する手段」である.JSX文法が一般的に使われているので、反応セグメントの存在がわからないかもしれません.JSX構文は、バーベルをReact.createElementメソッドを呼び出すコードに変換する.
反応層を理解することは、反応が内部でどのように動作しているかを理解するのに役立ちます.レンダリングのパフォーマンスを向上させるために、リアクターは仮想ドームを使用します.ブラウザでドームを変更するには時間がかかります.したがって、すばやくレンダリングするには、ドームの変更を最小限に抑えることが望ましい.
リアクションは、リアクションユニットからなる仮想ドームをメモリに格納し、再評価すると、新しく返されたリアクションユニットからなる仮想ドームを以前の仮想ドームと比較します.だから私たちは変化した部分だけを実際のドームに反映する戦略を取った.
反応要素を使用して仮想ドームを作成し、実際のドームに反映する変更を検索します.
const element = (
    // JSX 문법은 리액트 엘리먼트(객체)를 반환한다
    <a key="key1" style={{ color: blue }} href="https://google.com">
        Click here
    </a>
);

console.log(element);
次の反応要素(要素変数)をコンソールに出力すると、次のオブジェクトが出力されます.
Object {
    type: 'a',
    key: 'key1',
    ref: null,
    props: {
        href: 'https://goggle.com',
        style: {
            color: blue
        },
        children: 'Click here'
    },
    // ,,
}
まず、[オブジェクトタイプ](Object Type)に反応エンティティが含まれていることがわかります.文字列aは、typeというpropertyに入力される.これは、keyというpropertyにkey 1が入力され、propsの値にhref、style、childrenを含むオブジェクトが含まれるタグが使用されるためです.
上記のコードでは、応答領域はhtml要素が内蔵されているため、typeに「文字列」が入力され、ユーザ要素を使用して応答領域を作成する場合は以下のようになります.
function Title({ title, color }) {
    return <p style={{ color }}>{title}</p>;
}

const element = <Title title="hello" color="blue" />;

console.log(element);
応答エンティティは、次のようにコンソールに出力されます.
Object {
    type: Title, // 함수 참조가 할당, 함수가 다시 호출된다.
    props: {
        title: 'hello',
        color: 'blue'
    }
    //,,
}
なお、要素「関数(関数要素)」はtypeにバインドされている.この関数を使用すると、レンダーに十分な情報が得られます.反応器はこの関数を実行し、結果として反応器(<p style={{ color: blue }}>hello</p>)を得る.
また、リアクションエンティティが「不変オブジェクト」であるため、変更しようとするとエラーが発生します.
const element = <a href="https://goggle.com">Click here</a>";

element.type = 'b'; // 리액트 엘리먼트는 불변 객체이므로 변경 불가능, 에러 발생
Virtual DOM
1つの画面を表示するには、ツリー構造に複数の反応領域が含まれます.
<div>
    <p>안녕하세요</p>
    <div>
        <p>이름: 홍길동</p>
        <p>나이: 23</p>
    </div>
</div>
上のJSXコードは、以下の反応シンボルツリーから構成されています.
{
    type: 'div',
    props: {
        children: [
            {
                type: 'p',
                childrend: '안녕하세요'
            },
            {
                type: 'div',
                props: {
                    children: [
                        {
                            type: 'p',
                            children: '이름: 홍길동'
                        },
                        {
                            type: 'p',
                            childrend: '나이: 23'
                        }
                    ]
                }
            }
        ]
    }
}
プログラム画面は、さまざまなイベントによって異なる外観を示します.「反応要素ツリー」は、時間とともに画面上の「瞬間」を表します.
応答では、データの変更(ステータス値の変更)による画面の更新がレンダーステップ(Render Step)とコミットステップ(Submit Step)を経験します.
ステータス値はpropsでサブエレメントに渡してもよいし、contextで他のエレメントに渡してもよい.

  • レンダーステップ(Render Step):実際のドームに反映する変更を決定するには

  • ステップの発行:確定した変更を実際のドームに反映するには
  • レンダリングフェーズでは、[仮想ドーム](Virtualドーム)を使用して変更を決定します.仮想ドームは応答エンティティとして作成され、応答はレンダリングのたびに新しい仮想ドームを作成し、以前の仮想ドームと比較されます.これは、実際のドームの変更を最小限に抑えるプロセスです.
    function Todo({ title, desc }) {
        const [priority, setPriority] = useState('high');
        
        const handleClick = () => {
            setPriority(priority === 'high' ? 'low' : 'high');
        }
        
        return (
            <div>
                <Title title={title} />
                <p>{desc}</p>
                <p>{priority === 'high' ? '우선순위 높음' : '우선순위 낮음'}</p>
                <button onClick={handleClick}>우선순위 변경</button>
            </div>
        );
    }
    
    const Title = React.memo(({ title }) => {
        return <p style={{ color: 'blue' }}>{title}</p>;
    });
    
    ReactDOM.render(<Todo title="study" desc="React" />, document.getElementById('root'));
    上記コードでは、Todo素子によって作成された反応層を以下に示す.
    {
        type: Todo,
        props: {
            title: 'study',
            desc: 'React'
        },
        //,,
    }
    上記のオブジェクトが作成されるべきであり、typeはTodo構成部品関数を含む.propsには渡された値が表示されます.リアクターは、レンダリング結果を得るためにTodo要素関数を呼び出します.結果は次のとおりです.
    {
        type: 'div',
        props: {
            children: [
                {
                    type: Title,
                    props: {
                        title: 'study'
                    }
                },
                {
                    type: 'p',
                    props: {
                        children: 'React'
                    }
                },
                {
                    type: 'p',
                    props: {
                        children: '우선순위 높음'
                    }
                },
                {
                    type: 'button',
                    props: {
                        onClick: function() {,,,},
                        children: '우선순위 변경'
                    }
                }
            ]
        }
    }
    この結果、Todo要素の戻り文で作成された構造と同じ反応層が作成されます.しかし、type値にはTitle素子が存在するため、この反応セグメントツリーを実ドームにすることはできない.「反応セグメントツリー」を実際のドームにするには、すべての反応セグメントのtypeパーセント値が「文字列」である必要があります.
    Title構成部品をレンダリングした結果は次のとおりです.
    {
        type: 'p',
        props: {
            style: { color: blue },
            children: 'study'
        }
    },
    // ,,
    重合反応要素のtypeのパーセント値が文字列であるため、実際のドームとして作成することができる.実際のドームを作成できる反応シンボルツリーを「仮想ドーム」と呼びます.
    最初の反応シンボルツリーから仮想ドームを作成し、以前の仮想ドームを現在の仮想ドームと比較して、実際のドームの違いを反映します.
    最初のレンダリング結果は、実際のドームに反映されます.次に再レンダリングすると、現在作成されている仮想ドームと比較して、[実際のドームに変更された部分のみを反映](反映する部分のみ)になります.ブラウザで実際のドームを変更するには、他の操作よりも時間がかかるため、必要な部分だけを変更することが重要です.
    レンダーステップは、ReactDOM.renderメソッドを呼び出すか、構成部品でステータス値関数の変更(Change Status Value Function)を呼び出すかから開始できます.上記の例では、ReactDOM.renderメソッドによって開始されるレンダリング手順について説明した.
    次に、ステータス値変更関数のレンダリング手順に従います.
    [優先度を変更](Change Priority)ボタンを押すと、構成部品の状態の優先度の値が変更され、次のような[リアクションシンボルツリー](Reactive Metro Tree)(仮想ドーム)が作成されます.
    {
        type: 'div',
        props: {
            children: [
                {
                    type: Title,
                    props: {
                        title: 'study'
                    }
                },
                {
                    type: 'p',
                    props: {
                        children: 'React'
                    }
                },
                {
                    type: 'p',
                    props: {
                        children: '우선순위 낮음' // -> 값 변경
                    }
                },
                {
                    type: 'button',
                    props: {
                        onClick: function() {,,,},
                        children: '우선순위 변경'
                    }
                }
            ]
        }
    }
    以前の仮想ドームと比較して、文字列のみが「低優先度」に変更されました.そのため、実際のドームにもこの部分しか反映されていません.

  • オブジェクトタイプのリアクションエンティティは、ツリー構造として表示され、「仮想ドーム」と呼ばれます.

  • 作成した仮想ドームはメモリに保存され、後で新しい仮想ドームを作成するときに、以前の仮想ドームと現在の仮想ドームを「比較」し、「変更が必要な場所のみ」で実際のドームを反映します.

  • データ変更後に画面を更新するには、[レンダリングステップ](Render Step)と[コミットステップ](Submit Step)があります.[レンダリング](Rendering)フェーズは、2つの仮想ドームを比較する[相違を検索](Find Differences)フェーズ、[コミット](Submit)フェーズは[実際のドームに検出された相違を反映](反映)フェーズです.
  • ReactDOM.renderメソッドが呼び出されると、最初のレンダリングステップが実行され、作成された仮想ドームを使用して実際のドームが作成されます.その後、ステータス値を変更すると、2番目のレンダリングステップが実行され、新しい仮想ドームが作成されます.以前の仮想ドームを現在の仮想ドームと比較し、変更した部分だけを実際のドームに反映します.