JSX-詳細

反応する高度なチュートリアル。パート1


この出版物を使用して、公式のReact.jsライブラリドキュメントのAdvanced Guidesセクションの一連の翻訳を開きます。


JSX-詳細


基本的に、JSXはReact.createElement(component, props, ...children)関数の構文糖衣です。



JSXコード:


 <MyButton color="blue" shadowSize={2}> Click Me </MyButton> 

コンパイル先:


 React.createElement( MyButton, {color: 'blue', shadowSize: 2}, 'Click Me' ) 

子孫を持たないタグには、自己閉鎖形式を使用することもできます。 例:


 <div className="sidebar" /> 

コンパイル先:


 React.createElement( 'div', {className: 'sidebar'}, null ) 

Babelオンラインコンパイラを使用して、さまざまなJSXコンストラクトがJavaScriptでどのようにコンパイルされるかをテストできます。


反応要素タイプの仕様


JSXタグの開始は、Reactエレメントのタイプを定義します。


大文字で定義されたタイプは、タグがReactコンポーネントを参照することを示します。 これらのタグは、コンパイル中に、Reactコンポーネントを含む名前付き変数を参照します。 したがって、この変数はスコープ内になければならないことに注意してください。 例:JSX式- <Foo />を使用する場合、変数Fooはスコープ内になければなりません。


Reactはスコープ内にある必要があります


なぜなら JSXはReact.createElement関数React.createElementコンパイルされ、 Reactライブラリは常にJSXコードのスコープ内にある必要があります。


たとえば、このコードでは両方のインポート行が必要です。 ReactCustomButton JavaScriptに直接含まれCustomButtonいません。


 import React from 'react'; import CustomButton from './CustomButton'; function WarningButton() { // return React.createElement(CustomButton, {color: 'red'}, null); return <CustomButton color="red" />; } 

JavaScriptラッパーを使用せず、Reactを<script>に直接追加する場合、Reactは常にグローバルスコープになります。


JSXタイプでドット表記を使用する


Reactコンポーネントは、JSXのドット表記を使用して参照できます。 これは、複数のReactコンポーネントをエクスポートするモジュールがある場合に便利です。 たとえば、 MyComponents.DatePickerがコンポーネントの場合、この表記をJSXで直接使用できます。


 import React from 'react'; const MyComponents = { DatePicker: function DatePicker(props) { return <div>Imagine a {props.color} datepicker here.</div>; } } function BlueDatePicker() { return <MyComponents.DatePicker color="blue" />; } 

React Standard Libraryの一部ではない新しく定義されたコンポーネントは大文字にする必要があります。


要素タイプが小文字の場合、これは、要素が<div><span>などのインラインコンポーネントであり、文字列'div'または'span'としてReact.createElement関数にReact.createElementれることをReact.createElementます。 <Foo />などの大文字のタイプはReact.createElement(Foo)としてコンパイルされ、JavaScriptファイルで定義またはインポートされたコンポーネントを参照します。


コンポーネントには大文字で名前を付けることをお勧めします。 JSXで使用する前に小文字で名前を付けたコンポーネントがある場合は、大文字で名前を付けた変数に割り当てます。


たとえば、次のコードは期待されるものを返しません。


 import React from 'react'; // !        : function hello(props) { // !  <div> , .. div   HTML : return <div>Hello {props.toWhat}</div>; } function HelloWorld() { // ! React  <hello />  HTML , ..     : return <hello toWhat="World" />; } 

エラーを修正するために、 hello名前をHello変更し、JSXで<Hello />を使用します。


 import React from 'react'; // !       : function Hello(props) { // !  <div> , .. div   HTML : return <div>Hello {props.toWhat}</div>; } function HelloWorld() { // ! React ,  <Hello />  , ..     : return <Hello toWhat="World" />; } 

ランタイムタイプの選択


React要素タイプではジェネリック式を使用できません。 ジェネリック式を使用して要素のタイプを決定する必要がある場合は、最初に大文字で名前が付けられた変数に割り当てます。 これは、propsのプロパティの値に応じて異なるコンポーネントを表示するためにしばしば必要です。


 import React from 'react'; import { PhotoStory, VideoStory } from './stories'; const components = { photo: PhotoStory, video: VideoStory }; function Story(props) { // ! JSX     . return <components[props.storyType] story={props.story} />; } 

エラーを修正するために、大文字で名前が付けられた変数の型を割り当てました。


 import React from 'react'; import { PhotoStory, VideoStory } from './stories'; const components = { photo: PhotoStory, video: VideoStory }; function Story(props) { // ! JSX    ,    . const SpecificStory = components[props.storyType]; return <SpecificStory story={props.story} />; } 

JSXのプロパティ


JSXでプロパティを設定する方法はいくつかあります。


Javascript式


JavaScript式を中括弧{}で囲むことにより、プロパティに配置できます。 例:


 <MyComponent foo={1 + 2 + 3 + 4} /> 

MyComponentコンポーネントMyComponent場合、 props.foo MyComponent値は10になります。 式1 + 2 + 3 + 4はこの結果を返します。


ifまたはforループがJavaScriptの式ではないif 、JSXで直接使用することはできません。 したがって、それらは周囲のコードでのみ使用する必要があります。 例:


 function NumberDescriber(props) { let description; if (props.number % 2 == 0) { description = <strong>even</strong>; } else { description = <i>odd</i>; } return <div>{props.number} is an {description} number</div>; } 

文字列リテラル


文字列リテラルはプロパティに配置できます。 これら2つのJSX式は同等です。


 <MyComponent message="hello world" /> <MyComponent message={'hello world'} /> 

文字列リテラルを配置する場合-その値はHTMLの非スクリーニングになります。 これら2つのJSX式は同等です。


 <MyComponent message="&lt;3" /> <MyComponent message={'<3'} /> 

通常、プロパティに文字列リテラルを直接配置することは使用されず、ここでは完全性のためにのみ説明します。


デフォルトのプロパティはtrueです。


JSXコンポーネントでプロパティを指定し、その値を指定しない場合、プロパティのデフォルト値はtrueに設定されtrue 。 これら2つのJSX式は同等です。


 <MyTextBox autocomplete /> <MyTextBox autocomplete={true} /> 

この機能の使用はお勧めしません。 ES6の短いオブジェクト表記と混同しやすいです。たとえば、ES6の {foo}は、エントリ{foo: foo}短い表記であり、 {foo: true}ではありません。 この機能は、HTMLに存在するためにのみ追加されます。


属性を展開


プロパティを含むオブジェクトがあり、それをJSXに渡す場合は、 ...を「スプレッド」演算子として使用して、オブジェクトに含まれるすべてのプロパティを渡すことができます。 これら2つのコンポーネントは同等です。


 function App1() { return <Greeting firstName="Ben" lastName="Hector" />; } function App2() { const props = {firstName: 'Ben', lastName: 'Hector'}; return <Greeting {...props} />; } 

汎用コンテナを実装する場合、属性を展開すると便利です。 同時に、デプロイするとコードが汚くなる可能性があります。 コンポーネントにデプロイされると、オブジェクトのすべてのプロパティがプロパティとして転送されます。これには、コンポーネントが必要としないものや処理しないものも含まれます。 この構文を慎重に使用することをお勧めします。


JSXの子孫(子供)


開始タグと終了タグを含むJSX式では、これらのタグで囲まれたコンテンツは、コンパイル中に特別なプロパティprops.childrenます。 可能な子孫のタイプを見てみましょう。


文字列リテラル


開始タグと終了タグの間に行を挿入すると、 props.childrenの値はこの行に等しくなります。 文字列リテラルを使用すると、多くの埋め込みHTML要素に便利です。


次のようになります。


 <MyComponent>Hello world!</MyComponent> 

この有効なJSX式props.childrenは、文字列"Hello world!"設定され"Hello world!" 。 文字列リテラルの値は、コンパイル時にHTMLによって選別されないため、一般的な単純化されたケースでは、HTMLを記述するのと同じようにJSXコードを記述できます。


 <div>     - &amp;.      HTML    JSX.</div> 

JSXは、行の先頭と末尾のスペースを削除します。 また、空白行も削除します。 タグに隣接する改行は削除されます。 文字列リテラルの中央に位置し、次々と続く改行は、単一の改行に変換されます。 したがって、次の例は同じように表示されます。


 <div>Hello World</div> <div> Hello World </div> <div> Hello World </div> <div> Hello World </div> 

Jsx要素


他のJSX要素は、JSX要素の子孫として機能できます。 これは、ネストされたコンポーネントを表示するのに便利です。


 <MyContainer> <MyFirstComponent /> <MySecondComponent /> </MyContainer> 

文字列またはJSX要素など、あらゆるタイプの子を混在させることができます。 これは、JSXがHTMLのように見える別のオプションです。 次の例は、JSXおよびHTMLで有効です。


 <div>  : <ul> <li>1-  </li> <li>2-  </li> </ul> </div> 

Reactコンポーネントは複数のReact要素を返すことはできません。つまり、Reactコンポーネントには常に最上位のルート要素が1つだけ必要です。 同時に、1つのJSX式には無制限の数の子を含めることができます。 したがって、最上位のルート要素がない場合は、前の例のように、要素のセットをdiv要素にラップするだけです。


Javascript式


JavaScript式を子として使用するには、単純に中かっこ{}で囲みます。 たとえば、次の式は同等です。


 <MyComponent>foo</MyComponent> <MyComponent>{'foo'}</MyComponent> 

この機能は、任意の長さのJSX式のリストを表示するためによく使用されます。 たとえば、次のコードはHTMLのリストを表示します。


 function Item(props) { return <li>{props.message}</li>; } function TodoList() { const todos = ['finish doc', 'submit pr', 'nag dan to review']; return ( <ul> {todos.map((message) => <Item key={message} message={message} />)} </ul> ); } 

JavaScript式は、他のタイプの子孫と組み合わせることができます。 これは、文字列パターンを表示するときに便利です。


 function Hello(props) { return <div>Hello {props.addressee}!</div>; } 

JavaScript関数


通常、JSXで使用されるJavaScript式は、文字列、React要素、またはその両方を一緒に返します。 ただし、 props.childrenは、Reactが表示方法を認識している型のデータだけでなく、あらゆる種類のデータを渡すことができる他のプロパティと同じように機能します。 たとえば、特定のコンポーネントを定義し、 props.children介してそのコンポーネントからコールバックを受け取ることができます。


 function ListOfTenThings() { return ( <Repeat numTimes={10}> {(index) => <div key={index}>This is item {index} in the list</div>} </Repeat> ); } //  " -   " numTimes      function Repeat(props) { let items = []; for (let i = 0; i < props.numTimes; i++) { items.push(props.children(i)); } return <div>{items}</div>; } 

子孫としてコンポーネントに何でも渡すことができます。 主なことは、このコンポーネントは、Reactが表示方法を知っているものを変換して、表示(レンダリング)の瞬間に戻す必要があるということです。 このような使用は一般的に受け入れられていませんが、Reactの能力を完全に反映しています。


ブール、ヌル、未定義は無視されます


falsenullundefinedおよびtrueは、子孫として使用できます。 ただし、これらの値はレンダリング時に表示されません。 次のJSX式は同じように表示されます。


 <div /> <div></div> <div>{false}</div> <div>{null}</div> <div>{true}</div> 

この機能は、JavaScriptの条件付き処理機能とともに、React要素を条件付きで表示するために使用できます。 showHeadertrue場合、次のJSX式は<Header />を表示しtrue


 <div> {showHeader && <Header />} <Content /> </div> 

ただし、Reactによって数値0などの「偽の」値が表示される場合は注意が必要です。 たとえば、次のコードは期待どおりに動作せず、 props.messagesに空の配列が含まれている場合、レンダリングの結果として0が表示されます。


 <div> {props.messages.length && <MessageList messages={props.messages} /> } </div> 

状況を改善するには、 &&前の式&&常にブールであることを確認してください。


 <div> {props.messages.length > 0 && <MessageList messages={props.messages} /> } </div> 

逆に、レンダリング時にfalsetruenullまたはundefinedを表示する必要がある場合- 文字列に変換します


 <div>   myVariable = {String(myVariable)}. </div> 

次の部分:



出典: React-上級ガイド-JSXの詳細



Source: https://habr.com/ru/post/J319270/


All Articles