3 JSXについての一般的な誤解


私は個人的にJSXが反応で使用されているのを見て嫌悪しています.長年、私はそれを使用することに対して非常に強い意見を持っていました.
私は、私が持っていた3つの誤解を共有したいです、そして、どのように、私はこれらのものがあなたが特定の観点からそれを見るとき、完全に真実でないと理解しました.

You're going to find that many of the truths we cling to depend greatly on our own point of view - Obiwan Kenobi


私は、JSXがどんな欠陥なしででも持つと説くようにしません.他のツールと同様に、ツールはあなたがそれを使用する方法と同じくらい良いです.
JSX 現在でも使用されていますReact , プロジェクトにMDX , VueJS , StencilJS , SolidJS , Mitosis , AtomicoJS and Preact . このブログでは、私はJSXに関する私の考えを説明するために反応の文脈に集中しています.

心配の分離


JSXはJavaScriptとHTMLを一緒にミックスします.これは、私たちがレイアウト&ロジックの混合のための懸念の分離のマントラに反対しようとしていることを意味します.
JSXを使用してプレゼンテーションコードを書くのは必ずしもこれらの原則をあきらめるわけではありません.この非常に単純な成分を見てみましょう
const HelloWorld = ({name}) => {
   const message = `Hello ${name}`;

   return <h1>{message}</h1>
}
JavaScriptのコンテキストでその分離が発生しない理由はありません.この例では、レイアウトとロジックは次のように分離されます.
const HelloWorld = ({name}) => {
   // component logic is confined above the JSX block
   // some logic to form message
   const message = `Hello ${name}`;

   // JSX is confined to this return block
   return <h1>{message}</h1>
}

One important thing to note is that separation of concerns is not equal to separation of file types. In modern UI development, we have found that instead of dividing the codebase into three huge layers that interweave with one another, it makes much more sense to divide them into loosely-coupled components and compose them. Inside a component, its template, logic and styles are inherently coupled, and collocating them actually makes the component more cohesive and maintainable. - VueJS Documentation


これを理解するために、このコンポーネントをAngular コンポーネント.
@Component({
  selector: 'hello-world',
  // template is confined in this property
  template: `<h1>{{message}}</h1>`
})
export class HelloWorldComponent {
  // component logic is confined in this class
  message: String;

  @Input()
  public set name(name: string) {
    // some logic to form message
    this.message = `Hello {name}`;
  }

}
角では、テンプレートをファイルを使用して分離できます.私はMVVM/MVCの用語を使用して適切にここで何が起こっているかを説明します.
コンポーネントController
@Component({
  selector: 'hello-world',
  templateUrl: './hello-world.html',
})
...
コンポーネントView
<h1>{{message}}</h1>
テンプレート/レイアウトの例はとても簡単ですので、実際にJSXの暗い側面を表示しないと言うかもしれません.我々は、それを条件で投げることによって少しそれを切り替えることができました.
日本学術振興会
{render && <h1>{message}</h1>}
角テンプレート
<h1 *ngIf="render">{{message}}</h1>
上で見ることができるように、JSXはJavaScriptとHTMLを使用して、上記と同じように、角の導入*ngIf .
この場合、実際の条件論理は、両例のレイアウトと実際に混在する.JavaScriptのコンテキストでは、反応して分離したり、角度のファイルで区切ってください.
反応して、レイアウトはコンポーネントと同じファイルにあります.これにより、コンポーネントコンテキストについての明確なアイデアが得られます.しかし、あなたは時間が非常に長いファイルを持っているでしょうVue SFCs . 幸運にも、エディタは、現在、同じファイルの異なるセクションで働くことができるようにウインドウを分割する方法を持っています.
私がここで述べたとしても、あなたはJSXをreturn コンポーネントの一部.確かに誰もこれを行うことを停止しています.
const HelloWorld = ({name}) => {
   const message = <h1>{`Hello ${name}`}</h1>;

   return message;
}
複数のコンポーネントを使用して複数のJSX部分を宣言する必要がある場合は、これを実現するためのより良い方法を考えてください.

もう一つのテンプレート構文


JSXがJavaScriptでHTMLを書くことができるので、それを学ぶのが簡単であると主張している間、我々は実際に、我々がHTMLとJavaScriptを分離させようとしていたものの忌避であると思うことができます.
一般的なフロントエンドライブラリ/フレームワークでは、実際にHTMLを動的にしながらJavaScriptからHTML間の分離を維持するためのさまざまなソリューションが付属しています.Angular Template Syntax , VueJS Template Syntax .
JSXテンプレート構文や反応テンプレート構文のようなものがないことに気がつきましたか?This おそらくJSXを説明するページだけで、それは非常に短いドキュメントです.それはそれのように見えるが、JSXはテンプレートエンジンではないHandlebars 私が上でリンクしたものと同様のテンプレートエンジンです.
JSXは実際よりもJavaScriptの構文拡張です.基本的に、JavaScriptを拡張してHTML/XMLのような構造をJavaScriptで使用することができます.
あなたが実際に上でリンクされたドキュメンテーションを見るならば、JSXと比較してこれらのテンプレートエンジンを始めることを学ぶために、多くがあります.JSXでは、最低限では、JavaScriptとHTMLといくつかの余分な例外を知る必要があります.JSXのループを使用して項目をレンダリングする例です.
<div>
 {names.map(name => (
    <li>
      {name}
    </li>
 ))}
</div>
これを見て、あなたはJavaScript.map HTMLを行うdiv and li そして、余分{} JavaScriptコードの評価.私は、これが最初にきれいに見えないということを知っています.しかし、ここで起こっていることを通してあなたを歩かせてください.
<div>{}</div>
JSXでは、HTMLとJSは有効なJSXと見なされます.しかし、HTMLの中でJPをスラップするには{} . さあ、中を見ましょう{} .
names.map(name => (<li>{name}</li>))
これはJavaScriptのコレクションを返します<li/> これはHTMLであるが、JSXでも有効なJavaScriptと見なされます.
MVVM/MVCフレームワークでテンプレートがどのように行われているかに対して、我々は反応とJSXが行くと考えることができますが、それは完全に真実ではありません.ここでは非常におなじみのように見える人気のバックエンドフレームワーク上のいくつかのテンプレートエンジンです.
ブレードテンプレート( PHP )
<div>
@foreach ($name as $names)
   <li>{{ $name }}</li>
@endforeach
</div>
かみそりのテンプレート
<div>
@foreach (var name in names)
{
  <li>@name</li>
}
</div>
神社テンプレート( Python )
<div>
{% for name in names %}
  <li>{{name}}</li>
{% endfor %}
</div>
あなたが見ることができるように、これはPHP、C .あなただけの言語と実際にそれを覚えていくつかのエキストラを知っている.
さあ、フロントエンドに戻りましょう.ハンドルバー、vuejs、角のテンプレートエンジンを見てみましょう.
ハンドル
<div>
{{#each names}}
   <li>{{this}}</li>
{{/each}}
</div>
ブイ
<div>
  <li v-for="name in names">{{name}}<li>
</div>
角度
<div>
  <li *ngFor="let name of names">{{ hero }}</li>
</div>
私は認めなければなりません、これらは私の意見できれいに見えます.しかし、一度柱や属性が特定の数になると、コントロール構造のスコープとコンテクストを特定するのは難しくなるでしょう.また、カスタム属性の多くを覚えておく必要があります.それ以外に、それはちょうど使用にかかります.
私のポイントを家に運転するために、JSXはテンプレートエンジンではありません、しかし、それはもう一つのテンプレートエンジンが何年もしてきたことをするのを許します.その上、JavaScriptとHTMLを扱っているので、非常に身近に見えます.
JSXの他のテンプレートを使用するよりも、この記事の紹介で言及したリンクのリストを参照することができます.あなたが反応が好きでないならば、あなたはまだそれらのプロジェクトからJSXを使うことを考慮することができました.
個人的には、私はJSXのようになったことは反応しなかった.それはStencilJS . 私は最終的にそれのハングアップを得たとき、私は最終的に2番目のチャンスを反応させると考えた.

フレキシブル


私は、これが有効なラントでありえたことに同意します.あまりにも柔軟性があるものと同様に、それは容易に虐待されることができました.JSXでは、JavaScriptとHTMLだけを探すべきです.また、反応を知っていない人のために混乱させる反応のコンポーネントを使用することができます.
JSXの反応要素も機能です.したがって、JSXはこのような暗号コードを作成するために使用できます


ロドリゴポンボ

そんなことはない
午後18時38分- 2018年5月02日
これにはいくつかのユースケースがあるかもしれませんが、おそらくこれを行うことはできません.このコードの実際の実装はありませんが、これはContext and Render Props 特に反応しているフードの下で.
あなたがJSXを調べているならば、あなたは反応を調査していて、何を不思議に思うでしょうRender Props そうです.私はこれを反応コースに変えたくありませんRender Props 仕事.
私はジェネリックを作成したいMouse コンポーネント内のマウスのx座標とy座標を出力するコンポーネント.X座標とY座標を好きなように表示できます.だから、我々はどのように反応でそれを行うにはRender Props .
マウスコンポーネント(反応)
const Mouse = ({children, onMouseMove}) => {
  const [coords, setCoords] = useState({x:0,y:0});

  const onMouseMove = (event) {
    setCoords({x: event.clientX, y: event.clientY});
  }
  return (<div onMouseMove={onMouseMove}>
     children({
       x: coords.x, 
       y: coords.y
     })
  </div>)
}
マウスコンポーネントを使用する
<Mouse>
  ({x,y}) => {
     return <h1>The mouse position is ({x}, {y})</h1>
  }
</Mouse>
この例では、Mouse コンポーネントは関数を受け入れ、JSXブロックでその関数を呼び出します.渡される関数もJSXを返します.
これはJavaScriptでの高機能関数がどのように機能するかに似ています.高次関数は、関数を引数として、関数を返す関数です
これを角で行うようにしましょう.
マウスコンポーネント(角)
@Component({
  selector: 'mouse',
  template: `
  <div (mousemove)="handleMouseMove($event)">
    <ng-container *ngTemplateOutlet="template; context: coords" ></ng-container>
  </div>
  `,
})
export class Mouse {
  @ContentChild(TemplateRef) template;
  coords = { x: 0, y: 0 }

  handleMouseMove(event) {
    this.coords = {
      x: event.clientX,
      y: event.clientY
    }
  }
}
マウスコンポーネント(角)を使用する
<mouse>
  <ng-template let-x="x" let-y="y">
     <h1>The mouse position is ({{x}}, {{y}})</h1>
  </ng-template>
</mouse>
私は実際には、これは何を知っているng-template , ng-container , and TempalateRef 彼らは実際にどのように動作します.JSXで、我々は短い簡潔なコードで好きなものを達成することができました.

結論


私がここで行ったことについては何も魅力的ではありません.いくつかの技術はかなりの時間の間、何らかの種類のテンプレートエンジンを使用していました.私は今でもJSXと一緒に仕事をしていても、テンプレートで作業するのが好きです.
多分、我々は実際にそれを憎む前にかなりの時間のために何かを使い始めるべきです.テンプレート対JSXの使用は、非常にあなたが構築しているアプリケーション、チームの好み、経験、またはおそらくあなたのチームのコードを使用可能なデザイナーを持っているかどうかに依存します.
何が好きですか、またはJSXについて好きではないですか?あなたの考えを共有してください.