[react]-レッスン4


babel充填が必要


babel自体はES 6構文で記述されたコードをES 5環境で実行可能なコードに変換しますが、ES 5に存在しない構文は変換できません.(ex Promise, Map, Set...) そのため、バーベル多機能ペンを増やす必要がある.
const numbers = [101, 201, 301];

// Array.prototype.find method
let findedTwoZeroOne = numbers.find(n => n === 201);

console.log({findedTwoZeroOne});

// Promise
function delay(timeout = 1000) {
  return new Promise((resolve) => {
    window.setTimeout(() => resolve(), timeout);
  });
}

delay().then(() => {
  console.log('call out');
});
findおよびPromiseの場合、IEはコードをサポートしない可能性が高い.なぜなら、コードは変換されず、保持されていないからである.そこでpolyfillを使用します.最近core-jsが推奨されているのでcore-jsを使用します.

注意:https://babeljs.io/docs/en/babel-polyfill#docsNav

レスポンス構成部品モジュールの管理


既存の構成部品を分離してファイルごとに構成部品を作成すると、次のエラーが発生します.

これはeslintで発生したJSXエラーで、JSXはRECTスキャンの範囲内でなければならないので、以下のコードを書くことができます.Headline.js
const { React } = window;

export function AppHeadline() {
  return <h1>Declarative programming</h1>;
}
しかし、Description.jsの要約が含まれている箇所があり、応答コンポーネントはHTMLではないため、要約エスケープ処理を記述する必要がある(「).

JavaScriptでは現在タイプをチェックできないため、以下のエラーが発生しました.

このエラーをeslintから閉じるには、eslintプロファイルにreact/prop-types:offを追加します.

@babel/独立モジュールロードの問題


構成部品をindexに分離します.htmlから直接ロードしようとすると、次のエラーが発生します.

これは、jsファイルのjsxが標準ではないため、次のエラーが発生します.
したがって、<script type="text/jsx" ... </script>に変更すると、次のエラーが発生します.

このエラーは、ブラウザがrequireを認識できないため、バーコードにコンパイルされ、ブラウザで次のコードを表示できます.

ブラウザは最終的にrequireを認識できないため、.babelrcファイルに入ってesmモジュール識別を行います..babelrc
    "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false
      }
    ]
  ]
また、スクリプトラベルも以下のようにdata-type="module"を含む.
 <script type="text/babel" data-type="module" src="./src/main.js"></script>
注意:https://babeljs.io/docs/en/babel-standalone#usage
これにより、先ほどのエラーは解消されますが、パス上の問題が発生します.
最終的にこの問題はbabel/独立そのものの問題であるため,別の根本的な解決方法が必要である.
に質問
  • main.jsファイルはbabel呼び出しモジュールとコンパイルモジュールを使用できますが、
  • main.jsファイルで呼び出された他のモジュールの呼び出しパスの問題を確認できます.
  • 他のモジュールファイルの呼び出しパスは正しく変更されますが、Babelによってコンパイルされません.
  • この問題を根本的に解決するためにBabel CLIを使用する.

    Babel Cli


    開発で使用したすべてのJSXコードに対してreactを行い,上記の問題を解決する.BabelをcreateElementAPIとして使用して処理する必要があります.
    このため、以下のパッケージをインストールします.
    npm i -D @babel/{cli,plugin-transform-react-jsx}
    プラグインがインストールされています.プラグインアイテムに挿入してください..babelrc
    "plugins": ["@babel/plugin-transform-react-jsx"]
    設定が完了したら、包傑森に入り、バーベルコンパイルのために設定します.
    "scripts": {
      "start": "cross-env OPEN='/client' npm run dev",
      "dev": "run-p watch:compile serve",
      "serve": "node ./server/index.mjs",
      "lint": "eslint ./ --ignore-path .gitignore",
      "format": "prettier --write ./ --ignore-path .gitignore",
      "compile": "babel ./client/src -d ./client/dist",
      "test": "jest",
      "watch": "run-p watch:**",
      "watch:lint": "esw ./ --watch --color --ignore-path .gitignore",
      "watch:format": "onchange ./ -- npm run format {{changed}}",
      "watch:compile": "npm run compile -- --watch",
      "watch:test": "npm t -- --watchAll",
      "clear": "rimraf -rf ./client/dist"
    },
    package.jsonにwacth:compileというバーベルをコンパイルするためのスクリプトを配置し、mainにdistファイルのsrcを使用させる場合は、バーベルでコンパイルしたソースコードを使用してレンダリングします./client/index.html
    <script type="module" src="./dist/main.js"></script>
    その後、動作が正常であることを確認できます.

    モジュール化プログラミング実習


    その後,React素子を用いたモジュール化プログラミング実験を行うために,ウィンドウとは異なり,Retinaディスプレイ上に明確に表示するためにMacBookが2倍の画像を必要とするPigmaに設計されたいくつかのスキームを検討した.
    したがって,フィグマから写真を出力する際には2倍の数字を用いる.
    通常の写真の場合、jpgは最適化され、透明性が必要な写真の場合、pngファイル、単純な形状、ロゴ、コンポーネントはsvgを使用してファイルをエクスポートします.
    <svg title={title} width="54" height="16" viewBox="0 0 54 16" fill="none">
    svgのアクセス性を実現するために、タイトルまたはsvgフラグの周囲にaria−labelなどの要素を追加する方法がある.

    書式設定


    otfとttf形式があり、一般的にはOTF(mac用)、TTF(ウィンドウ用)と呼ばれ、曲線の表現に違いがある.OTFは,曲線の次数が高いほど曲線の表現が自由になり,解像度の単位が高いほど,表現も簡潔になる.

    応答にデフォルト値を指定する方法


    React DefaultProps
    注意:https://reactjs.org/docs/react-without-es6.html#declaring-default-props
    Logo.defaultProps = {
      textColor: '#242CF8',
      dotColor: '#FF6B00',
    };
    defaultPropsを使用してデフォルト値を設定できます.レンダリング時の仮想DOMの値がnullの場合、reactはレンダリング時に表示されないので、title={title}のように記述できます(titleに値が入力されていない場合は表示されず、値が存在する場合にのみ表示されます).

    ダミードーム


    仮想ドームは実際のDOMに直接操作するのではなく,変更要求が発生した場合に仮想DOMの前後構造を比較し,変更した部分のみを実際のDOMに更新する.DOMを実際に操作することなく、UIの反応速度を向上させることができるという.
  • 頻繁なDOM操作はコストが高く、速度が遅い.
  • Reactは,仮想DOMを用いて性能(速度)を向上させる方式を採用している.
  • 仮想DOMのコンポーネントを引き続き観察し、ステータスの変更を検出しようとします.
  • 仮想DOMの移行後比較(diff)は,再調整アルゴリズム(以前は協調,現在は光ファイバ)を用いて効率的に処理した.
  • 比較結果に差異が生じた場合、実際のDOMに反映されてUIが更新される.

  • バーチャルドーム実習


    仮想ドーム実験を簡単に行い、ファイル構造は以下の通りです.
    モジュール説明h.js仮想(仮想)DOMノードcreateElementを作成します.jsDOMノード(サブノードを含む)diff.js前後の仮想DOMノード比較を生成した後、変更したpropsを返します.js仮想DOMノードのprops(変更、抽出、レビュー、削除など)bindEventsを更新します.js仮想DOMノード上のイベントprops接続updateElement.js実際のDOMノードコンテナにマウント(マウント)→レンダリング(レンダリング)h.js
    export function h(type, props = {}, ...children) {
      return { type, props, children };
    }
    React.createElement()はtype, props, ...childrenをパラメータとする.同様に、仮想DOM構造を容易に作成するために、hyperscriptモジュールhを以下に示すように記述する.
    JSXアーキテクチャ
    ReactはJSXを使用して仮想DOMをより理解しやすく使用します.JSX構文は、Babelなどのコンパイラによって仮想DOMを生成する関数コードに変更されます.
    @babel/plugin-tranform-react-jsxプラグインを使用してJSX構文を特定の関数としてコンパイルできます.仮想DOMを生成するh()関数をJSX構文を解析する関数として設定できます.
    JSX構文を解釈して特定の関数に設定するには、コンパイラによって示される@jsxプラグを使用します.
    /** @jsx h */
    
    const vDomNode = (
      <ul className="what-is-virtual-dom">
          <li>가상 DOM은 실제 DOM을 추상화 하여 표현한 것을 말합니다.</li>
          <li>가상 DOM 트리에서 무언가 변경되면 새로운 가상 DOM 트리가 생성됩니다.</li>
      </ul>
    );
    h(
      'ul', 
      { className: 'what-is-virtual-dom' }, 
      h('li', null, '가상 DOM은 실제 DOM을 추상화 하여 표현한 것을 말합니다.'),
      h('li', null, '가상 DOM 트리에서 무언가 변경되면 새로운 가상 DOM 트리가 생성됩니다.'),
    )
    このため、JSX構文で記述しても、バーベルプラグイン変換で簡単に仮想ノードを作成できます.以下に、バーベルのホームページでコンパイラによって処理された結果を示します.
    createElement.js
    import { setProps } from './props.js';
    import { bindEvents } from './bindEvents.js';
    
    export function createElement(vNode) {
      if (typeof vNode === 'string') {
        return document.createTextNode(vNode);
      }
    
      const elementNode = document.createElement(vNode.type);
    
      setProps(elementNode, vNode.props);
      bindEvents(elementNode, vNode.props);
    
      vNode.children
        .map(createElement)
        .forEach(elementNode.appendChild.bind(elementNode));
    
      return elementNode;
    }
    createElement vNodeがテキストノードであるかどうかを確認し、テキストノードである場合はすぐに戻ります.他の場合、setPropsを使用して反応素子のpropsを設定し、bindEventsを使用してイベントを設定します.
    その後、サブノードを迂回して再帰的に呼び出し、現在のノードに貼り付けます.updateElement.js
    import { createElement } from './createElement.js';
    import { updateProps } from './props.js';
    import { diff } from './diff.js';
    
    export function updateElement(parentNode, newVNode, oldVNode, index = 0) {
      if (!oldVNode) {
        parentNode.appendChild(createElement(newVNode));
      } else if (!newVNode) {
        parentNode.removeChild(parentNode.childNodes[index]);
      } else if (diff(newVNode, oldVNode)) {
        parentNode.replaceChild(
          createElement(newVNode),
          parentNode.childNodes[index]
        );
      } else if (newVNode.type) {
        updateProps(parentNode.childNodes[index], newVNode.props, oldVNode.props);
    
        let i = 0;
        let newChildrenCount = newVNode.children.length;
        let oldChildrenCount = oldVNode.children.length;
    
        for (; i < newChildrenCount || i < oldChildrenCount; ++i) {
          updateElement(
            parentNode.childNodes[index],
            newVNode.children[i],
            oldVNode.children[i],
            i
          );
        }
      }
    }
    上記の関数にoldVNode、すなわち従来の仮想DOMノードがない場合は、貼り付けるだけです.また、新しい仮想DOMノードが渡されていない場合は、DOMから削除されたことを示すため、親ノードはインデックスに対応する子ノードを削除します.
    3つ目は、仮想DOMノードを比較し、変更が検出された場合はdiffモジュールを使用して新しいノードに置き換え、DOM要素のpropsが更新された場合は更新されます.最終的には、再帰呼び出しによってサブノードを更新します.diff.js
    export function diff(newVNode, oldVNode) {
      return (
        typeof newVNode !== typeof oldVNode ||
        (typeof newVNode === 'string' && newVNode !== oldVNode) ||
        newVNode.type !== oldVNode.type ||
        newVNode.props.forceUpdate
      );
    }
    転送された新しい仮想DOMを以前の仮想DOMと比較して、ノードが変更されたかどうかを確認します.