React.js:初心者向けガイド

私たちが翻訳している記事の著者は、残念ながら、既存のReactガイドのほとんどは、価値ある実用的な開発手法に十分な注意を払っていないと考えています。 これらのガイドは、Reactを操作するための「正しいアプローチ」が何であるかを常に関係者に理解しているとは限りません。



画像



このチュートリアルは、HTML、JavaScript、CSSの知識を持つ開発者を対象としていますが、Reactの基本と、このライブラリを使用するプログラマが遭遇する可能性のある最も一般的な間違いについて説明します。



Web開発者がReactを選択する理由



ビジネスに取り掛かる前に、ReactがWebインターフェースを開発するためのツールの中で最良の選択肢と考えられる理由について少し話してみましょう。 多くのUIフレームワークがあります。 Reactを選択する理由 この質問に答えるために、最も人気のある2つのインターフェース開発ツールであるReactとAngularを比較しましょう。 人気が高まっているVue.jsフレームワークをこの比較に含めることができますが、ReactとAngularに限定することに注意してください。



interfacesインターフェイスの記述への宣言的アプローチ



React開発では、ページに表示する必要のあるものを記述します(これを行う方法については、ブラウザーの指示をコンパイルすることではありません)。 これは、とりわけ、定型コードの量の大幅な削減を意味します。



一方、Angularには、コンポーネントの定型コードを生成するコマンドラインツールがあります。 これは、最新のインターフェース開発ツールに期待できるものとは少し違うように見えますか? 実際、Angularにはテンプレートコードが非常に多く、それを生成するために特別なツールが作成されているという事実について話している。



開発を始めたReactでは、彼らはコードを書き始めたところです。 何らかの方法で生成する必要のある定型的なコンポーネントコードはありません。 もちろん、開発の前にある程度の準備が必要ですが、コンポーネントに関しては、純粋な機能として説明できます。



▍明確な構文



角度コードは、 ng-model



ngIf



およびngFor



などのngFor



ます。 このコードはかなり面倒です。 一方、Reactでは、通常のHTMLとして認識されるJSX構文が使用されます。つまり、React-developmentを開始するために、根本的に新しいことを学ぶ必要はありません。 これは次のようなものです。



 const Greetings = ({ firstName }) => (  <div>Hi, {firstName}</div> );
      
      





▍正しい学習曲線



学習曲線は、UIフレームワークを選択する際に考慮すべき重要な要素です。 この点で、ReactではAngularよりも抽象化が少ないことに注意してください。 JavaScriptを知っていれば、おそらく文字通り1日でReactアプリケーションを作成する方法を学ぶことができます。 もちろん、それを正しく行う方法を学ぶには時間がかかりますが、非常に迅速に仕事に取りかかることができます。



Angularを分析する場合、このフレームワークをマスターすることにした場合、Angularコマンドラインツールの使用方法とディレクティブの操作に慣れるだけでなく、新しい言語を学ぶ必要があります(AngularはTypeScriptを使用します)。



dataデータバインディングメカニズムの機能



Angularには双方向のデータバインディングシステムがあります。 これは、たとえば、要素の形での変更がアプリケーション状態の自動更新につながるという事実で表現されます。 これはデバッグを複雑にし、このフレームワークの大きな欠点です。 このアプローチでは、何か問題が発生した場合、プログラマーはアプリケーションが状態を変更した原因を正確に知ることができません。



一方、Reactは一方向のデータバインディングを使用します。 これは、プログラマーが常にアプリケーションの状態の変化につながったものを正確に知っているという事実に表されているため、このライブラリの大きなプラスです。 データバインディングに対するこのアプローチにより、アプリケーションのデバッグが大幅に簡素化されます。



▍機能開発アプローチ



Reactの長所の1つは、このライブラリが開発者にクラスの使用を強制しないという事実だと思います。 Angularでは、すべてのコンポーネントをクラスとして実装する必要があります。 これは、利点を与えることなく、過度のコードの複雑さにつながります。



Reactでは、すべてのユーザーインターフェイスコンポーネントを純粋な関数のセットとして表現できます。 純粋な関数を使用してUIを形成することは、息を吹きかけることと比較できます。



ユーザーインターフェイスを開発するためのツールを選択するときに、この特定のライブラリに傾く可能性が非常に高いReactの人気の理由を検討したので、実践に移りましょう。



Reactアプリケーション開発プラクティス



▍Node.js



Node.jsはJavaScriptコードの実行をサポートするサーバープラットフォームであり、その機能はReact開発に役立ちます。 このプラットフォームをまだインストールしていない場合は、ここで修正します。



projectプロジェクトの準備



ここでは、Facebookのcreate-react-app



パッケージを使用して、Reactアプリケーションのコアを作成します。 これはおそらく、開発を開始できる作業環境をセットアップするための最も一般的なアプローチです。 create-react-app



おかげcreate-react-app



プログラマーは多くの必要なツールを自由に使用できるので、自分でそれらを選択する必要がなくなります。



create-react-app



にインストールcreate-react-app



には、次のコマンドを使用します。



 npm i -g create-react-app
      
      





次に、アプリケーションテンプレートを作成するには、次のコマンドを実行します。



 create-react-app react-intro
      
      





この準備は完了です。 アプリケーションを起動するには、次のコマンドを実行します。



 cd react-intro npm start
      
      





ここで、プロジェクトフォルダーに移動して開発サーバーを起動します。これにより、 http:// localhost:3000 /のブラウザーに移動して、新しいReactアプリケーションを開くことができます。



▍プロジェクトの構造



これで、Reactアプリケーションがどのように配置されるかを理解できます。 これを行うには、IDEを使用して作成したプロジェクトを開きます( Visual Studio Codeをお勧めします)。



Index.htmlファイル



プロジェクトフォルダーで、 public/index.html



あるファイルを開きます。 これにより、次のことがわかります。









Index.htmlファイル



ここでは、特に<div id="root">



という行に興味があります。 これは、Reactアプリケーションが配置される場所です。 この要素はすべてアプリケーションコードに置き換えられ、その他はすべて変更されません。



Index.jsファイル



src/index.js



開きsrc/index.js



。 Reactアプリケーションをデプロイするのはこのファイルです。 ところで、アプリケーションのソースコードはsrc



ディレクトリに配置されます。









Index.jsファイル



ページに「Reactアプリケーション」と呼ぶものを配置するコード行は次のとおりです。



 ReactDOM.render(<App />, document.getElementById('root'));
      
      





この行は、ReactにApp



コンポーネントを取得して(すぐに説明します)、調査したindex.html



ファイルで定義されたroot



div



配置する必要があることを伝えます。



次に、 <App />



コンストラクトを扱います。 HTMLコードに非常に似ていますが、Reactが使用する特別なJavaScript構文であるJSXコードのサンプルです。 この構造は大文字のA



で始まり、 <app />



ではなく<app />



<App />



であることに注意してください。 これは、Reactで使用されるエンティティの命名規則によるものです。 このアプローチにより、システムは通常のHTMLタグとReactコンポーネントを区別できます。 コンポーネント名が大文字になっていない場合、Reactはそれらをページに表示できません。



一部の.js



ファイルでJSXを使用する予定がある場合は、次のコマンドを使用してReactをインポートする必要があります。



 import React from 'react';
      
      





App.jsファイル



これで、最初のコンポーネントのコードを見る準備ができました。 これを行うには、 src/App.js













App.jsファイル



Reactコンポーネントを作成するには、最初にReact.Component



子孫であるクラスを作成する必要があります。 これは、 class App extends Component



ラインが解決するものです。 すべてのReactコンポーネントにはrender



メソッドの実装が含まれている必要がありrender



メソッドでは、その名前から推測できるように、コンポーネントがレンダリングされ、視覚表現の説明が生成されます。 このメソッドは、ページへの出力用にHTMLマークアップを返す必要があります。



className



属性は、HTMLのclass



属性に相当することに注意してください。 スタイルを設定するためにCSSクラスを要素に割り当てるために使用されます。 JavaScriptのclass



キーワードは予約されているため、属性名として使用できません。



コンポーネントについて見つけたばかりのことを繰り返しましょう。



  1. 名前は大文字で始まります( App



    内のA



    )。
  2. React.Component



    クラスを拡張します。
  3. マークアップを返すrender



    メソッドを実装する必要があります。


それでは、Reactアプリケーションを開発する際に避けるべきことについて話しましょう。



▍推奨事項1:コンポーネントクラスをどこでも使用する必要はありません



Reactのコンポーネントは、2つのアプローチを使用して作成できます。 1つ目はコンポーネントクラス(クラスコンポーネント)を使用すること、2つ目は機能コンポーネント(機能コンポーネント)を使用することです。 お気づきかもしれませんが、上記の例ではクラスを使用しています。 残念ながら、ほとんどのReact初心者向けチュートリアルでは、それらの使用を推奨しています。



クラスメカニズムを使用してコンポーネントを記述することの何が問題になっていますか? 実際、そのようなコンポーネントはテストが難しく、過度に大きくなる傾向があります。 これらのコンポーネントは、低品質の責任の分離、ロジックと視覚的表現の混在という問題の影響を受けます(これにより、アプリケーションのデバッグとテストが複雑になります)。 一般に、コンポーネントクラスを使用すると、比the的に言えば、プログラマーは「自分の足で撃つ」という事実につながります。 したがって、特に初心者プログラマーの場合は、コンポーネントクラスをまったく使用しないことをお勧めします。



そのため、コンポーネントを記述するためにクラスを使用することはお勧めできません。 どのような選択肢がありますか? この質問に対する答えは、機能コンポーネントです。 クラスを使用して作成されたコンポーネントにrender



メソッドしか含まれていない場合、機能コンポーネントに処理するための優れた候補です。 このアイデアを武器に、 create-react-app



ツールによって作成されたApp



コンポーネントを改善する方法について考えてみましょう。



 function App() { return (   <div className="App">     ...   </div> ); } export default App;
      
      





ここで何をしたかわかりますか つまり、クラスを削除し、 render



メソッドをフォームfunction App() {...}



構築に置き換えました。 ここでES6矢印関数構文を使用すると、コードはさらに良くなります。



 const App = () => ( <div className="App">   ... </div> ); export default App;
      
      





クラスを、ページに表示する必要があるマークアップを返す関数に変えました。



これを考慮してください。 マークアップを返す関数には、定型コードはありません。 これはほとんど純粋なマークアップです。 それは完璧ではありませんか?



機能コンポーネントのコードは読みやすく、それらを操作するので、標準設計に対する注意散漫がはるかに少なくなります。



ここでは、機能クラスはコンポーネントクラスよりも望ましいと述べたが、この記事では主にクラスを使用することに注意してください。コンポーネントクラスのコードは初心者にとってより明確であるため、 Reactの重要な概念を説明するのは簡単です。 しかし、Reactアプリケーションの開発に慣れてきたら、実際のプロジェクトを開発する際に上記のことを考慮することを強くお勧めします。 機能コンポーネントをよりよく理解するために、 この資料をご覧ください。



propertiesプロパティに関する知識



プロパティ(props)は、Reactの中心概念の1つです。 「プロパティ」とは何ですか? これを理解するために、関数に渡されるパラメーターを覚えておいてください。 本質的に、プロパティはコンポーネントに渡されるパラメーターです。 次のコードを検討してください。



 const Greetings = (props) => <div>Hey you! {props.firstName} {props.lastName}!</div>; const App = () => ( <div>   <Greetings firstName="John" lastName="Smith" /> </div> );
      
      





ここでは、 Greetings



コンポーネントを作成し、それを使用して、 App



コンポーネントからJohn Smith



という名前の男性に挨拶します。 このコードはすべて、次のHTMLマークアップになります。



 <div>  <div>Hey you! John Smith!</div> </div>
      
      





{props.name}



ような式の中括弧は、JavaScriptコードを強調するために使用されます。 Greetings



コンポーネントは、パラメーターの形式で、 firstName



およびlastName



プロパティーに渡されます。 props



オブジェクトのプロパティを参照して、それらをprops



ます。



firstName



プロパティとlastName



プロパティを表す2つの値ではなく、単一のprops



オブジェクトがprops



props



ことに注意してください。



ES6のオブジェクトを再構築する機能を活用することで、コードを簡素化できます。



 const Greetings = ({ firstName, lastName }) => <div>Hey you! {firstName} {lastName}!</div>;
      
      





ご覧のとおり、ここでは(props)



コンストラクト(props)



({ firstName, lastName })



置き換えられ(props)



います。 この置換により、システムにprops



オブジェクトの2つのプロパティのみに関心があることを伝えます。 これにより、 props.firstName



などのオブジェクトプロパティを明示的に指定しなくても、 firstName



lastName



値に直接アクセスできます。



機能コンポーネントの代わりに同じ問題を解決するために、クラスベースのコンポーネントを使用するとしたらどうでしょうか? この場合、 Greetings



コンポーネントコードは次のようになります。



 class Greetings extends React.Component { render() {   return (     <div>Hey you! {this.props.firstName} {this.props.lastName}!</div>   ); } }
      
      





このコードがあなたにどんな感覚をもたらすのかはわかりませんが、補助的なメカニズムで過負荷になっているようです。 ここでは、特に、プロパティにアクセスするには、 this.props



という形式の構造を使用する必要があります。



▍唯一の責任原則



単一責任原則(SRP)は、従うべき最も重要なプログラミング原則の1つです。 彼は、モジュールは1つの問題のみを解決し、質の高い方法で解決する必要があると語っています。 この原則だけに従わずにプロジェクトを開発すると、そのようなプロジェクトのコードは、サポートできない悪夢のようなデザインに変わる可能性があります。



単独責任の原則にどのように違反することができますか? ほとんどの場合、これは、互いに関係のないメカニズムが同じファイルに配置されている場合に発生します。 この資料では、しばしばこの原則を参照します。



通常、初心者は多くのコンポーネントを1つのファイルに配置します。 たとえば、 Greetings



App



コンポーネントのコードは同じファイルにあります。 実際には、これはSRPに違反するため、実行しないでください。



ごく小さなコンポーネント( Greetings



コンポーネントなど)でさえ、個別のファイルに配置する必要があります。



Greetings



コンポーネントコードを別のファイルに配置します。



 import React from "react"; const Greetings = ({ firstName, lastName }) => (   <div>       Hey you! {firstName} {lastName}!   </div> ); export default Greetings;
      
      





次に、 App



コンポーネントでこのコンポーネントを使用します。



 import Greetings from "./Greetings"; const App = () => ( ... );
      
      





ファイル名はコンポーネントの名前と一致する必要があることに注意してください。 つまり、 App



コンポーネントのコードはApp.js



ファイルに、 Greetings



コンポーネントのコードはGreetings



ファイルなどに配置する必要があります。



applicationアプリケーションの状態に精通している



状態は、Reactのもう1つの中心的な概念です。 これは、アプリケーションデータが保存される場所、つまり変更可能な場所です。 フォームフィールドに入力したものを保存する必要がありますか? 使用状態。 ブラウザゲームでプレーヤーが獲得したポイントを保存する必要がありますか? これを行うには、アプリケーションの状態を使用する必要があります。



ユーザーが自分の名前を入力できるシンプルなフォームを作成しましょう。 ここで、コンポーネントを記述するために意図的にクラスを使用していることに注意してください。これにより、問題の概念をより簡単に示すことができます。 ここで 、クラスを使用して作成されたコンポーネントを機能コンポーネントに変換する方法について読むことができます



 import React from "react"; class SimpleForm extends React.Component { render() {   return (     <div>       <input type="text" name="firstName" />       <Greetings firstName="John" />     </div>   ); } } const App = () => ( <div>   <SimpleForm /> </div> );
      
      





ユーザーはフォームフィールドに何かを入力できますが、それは良いことです。 ただし、このコードを注意深く読んだ場合、ウェルカムページの出力でJohn



がユーザー名として常に使用されていることに気付くかもしれません。 これがすべてのユーザーの名前ではない場合はどうなりますか? もしそうなら、我々はあまり快適ではない位置に身を置く。



フィールドに入力された値を使用する方法は? ReactはDOM要素に直接依存しません。 イベントハンドラとアプリケーションの状態は、この問題の解決に役立ちます。



 class SimpleForm extends React.Component { state = {   firstName: "", }; onFirstNameChange = event =>   this.setState({     firstName: event.target.value   }); render() {   return (     <div>       <input type="text" name="firstName" onChange={this.onFirstNameChange} />       <Greetings firstName={this.state.firstName} />     </div>   ); } }
      
      





状態は、プロパティの形式でSimpleForm



コンポーネントのクラスに保存される単純なJavaScriptオブジェクトとして想像できます。 このオブジェクトに、 firstName



プロパティを追加します。



ここでは、 firstName



フィールドにイベントハンドラーを装備しました。 ユーザーがフィールドに少なくとも1つの文字を入力するたびに開始されます。 クラスでは、 onChange



プロパティは、次のコマンドが実行されるonChange



onFirstNameChange



処理を担当します。



 this.setState(...)
      
      





ここで、コンポーネントの状態が更新されます。 コンポーネントのステータスは直接更新されません。 これは、 setState



メソッドを使用してのみ行われます。 firstName



プロパティに新しい値を書き込むには、状態に書き込む必要があるものを含むオブジェクトをこのメソッドに渡すだけです。



 { firstName: event.target.value }
      
      





この場合、 event.target.value



は、ユーザーがフォームフィールドに入力した名前、つまり名前です。



onFirstNameChange



をメソッドとして宣言しなかったことに注意してください。 このようなことは、メソッドの形式ではなく、矢印関数を含むクラスプロパティの形式で宣言することが非常に重要です。 同様の関数をメソッドとして宣言すると、予想されるように、クラスではなく、このメソッドを呼び出すフォーム要素にバインドされます。 この小さなことは、初心者にとってしばしば混乱を招きます。 これは、コンポーネントクラスではなく、機能コンポーネントの使用を推奨する理由の1つです。



formフォームに入力されたデータを確認する



正規表現を使用してフォームに入力されたデータをチェックする簡単なシステムを実装します。 名前は少なくとも3文字で構成され、文字のみを含むことができると決めましょう。



onBlur



イベントハンドラーをコンポーネントに追加します。これは、ユーザーが入力フィールドを離れたときに呼び出されます。 別のプロパティをアプリケーション状態firstNameError



追加しfirstNameError



。 名前の入力中にエラーが発生した場合、フィールドの下にこれに関するメッセージが表示されます。



このコードを分析しましょう。



 class SimpleForm extends React.Component { state = {   firstName: "",   firstNameError: "", }; validateName = name => {   const regex = /[A-Za-z]{3,}/;   return !regex.test(name)     ? "The name must contain at least three letters. Numbers and special characters are not allowed."     : ""; }; onFirstNameBlur = () => {   const { firstName } = this.state;   const firstNameError = this.validateName( firstName );   return this.setState({ firstNameError }); }; onFirstNameChange = event =>   this.setState({     firstName: event.target.value   }); render() {   const { firstNameError, firstName } = this.state;   return (     <div>       <div>         <label>           First name:           <input             type="text"             name="firstName"             onChange={this.onFirstNameChange}             onBlur={this.onFirstNameBlur}           />           {firstNameError && <div>{firstNameError}</div>}         </label>       </div>       <Greetings         firstName={firstName}       />     </div>   ); } }
      
      





申請状況



入力検証システムを開発するために、まず、新しいプロパティを状態に追加しました: firstNameError







 state = {  ...  firstNameError: "", };
      
      





データ検証機能



データ検証は、 validateName



矢印関数で実行されます。 入力された名前を正規表現で検証します。



 validateName = name => { const regex = /[A-Za-z]{3,}/; return !regex.test(name)    ? "The name must contain at least three letters..."    : ""; }
      
      





検証が失敗した場合、関数からエラーメッセージを返します。 名前がテストに合格した場合、名前のチェック中にエラーが検出されなかったことを示す空の文字列を返します。 ここでは、簡潔にするために、三項演算子JavaScriptを使用します。



OnBlurイベントハンドラー



ユーザーが入力フィールドを離れたときに呼び出されるonBlur



イベントonBlur



見てonBlur







 onFirstNameBlur = () => { const { firstName } = this.state; const firstNameError = this.validateName( firstName ); return this.setState({ firstNameError }); };
      
      





ここでは、オブジェクトを破棄するES6の機能を利用して、状態からfirstName



プロパティを抽出します。 このコードの最初の行はこれと同等です:



 const firstName = this.state.firstName;
      
      





次に、上記のデータ検証関数を呼び出してfirstName



を渡し、この関数が返すものを状態プロパティfirstNameError



書き込みます。 チェックに失敗すると、エラーメッセージがこのプロパティに送信されます。 成功すると、そこに空の行が書き込まれます。



レンダリング方法



コンポーネントのrender()



メソッドを考えてみましょう:



 render() {  const { firstNameError, firstName} = this.state;  ... }
      
      





.



 <input ... onBlur={this.onFirstNameBlur} />
      
      





onFirstNameBlur



onBlur



.



 {firstNameError && <div>{firstNameError}</div>}
      
      





JavaScript. div



, , , firstNameError



true



.





, , , . , :



 render() { const { firstNameError, firstName } = this.state; return (   <div       style={{         margin: 50,         padding: 10,         width: 300,         border: "1px solid black",         backgroundColor: "black",         color: "white"       }}     >     <div style={{marginBottom: 10}}>       <label>         First name:         <input           style={{backgroundColor: '#EFEFFF', marginLeft: 10}}           type="text"           name="firstName"           onChange={this.onFirstNameChange}           onBlur={this.onFirstNameBlur}         />         {firstNameError && <div style={{color: 'red', margin: 5}}>{firstNameError}</div>}       </label>     </div>     <Greetings       firstName={firstName}     />   </div> ); }
      
      





React style



.



, , , , , . , .













▍ №2:



, , React-. , , — render



, , . なぜこれが悪いのですか? , . , , .



これを避ける方法は? , . style



, . . , style.js



:



 // style.js: const style = {   form: {       margin: 50,       padding: 10,       width: 300,       border: "1px solid black",       backgroundColor: "black",       color: "white"   },   inputGroup: {       marginBottom: 10   },   input: {       backgroundColor: "#EFEFFF",       marginLeft: 10   },   error: {       color: "red",       margin: 5   } }; export default style;
      
      





, , SimpleComponent



:



 import style from './style'; class SimpleForm extends React.Component {   ...       render() {       const { firstNameError, firstName } = this.state;         return (         <div style={style.form}>           <div style={style.inputGroup}>             <label>               First name:               <input                 style={style.input}                 type="text"                 name="firstName"                 onChange={this.onFirstNameChange}                 onBlur={this.onFirstNameBlur}               />               {firstNameError && (                 <div style={style.error}>{firstNameError}</div>               )}             </label>           </div>             <Greetings firstName={firstName} />         </div>       );     } } export default SimpleForm;
      
      





, . .





, :



 class SimpleForm extends React.Component { state = {   ...   lastName: "",   lastNameError: "" }; validateName = ...; onFirstNameBlur = ...; onFirstNameChange = ...; onLastNameBlur = () => {   const { lastName } = this.state;   const lastNameError = this.validateName(lastName);   return this.setState({ lastNameError }); }; onLastNameChange = event =>   this.setState({     lastName: event.target.value   }); render() {   const { firstNameError, firstName, lastName, lastNameError } = this.state;   return (     <div style={style.form}>       <div style={style.inputGroup}>         <label>           First name:           <input             style={style.input}             type="text"             name="firstName"             onChange={this.onFirstNameChange}             onBlur={this.onFirstNameBlur}           />           {firstNameError && <div style={style.error}>{firstNameError}</div>}         </label>       </div>       <div style={style.inputGroup}>         <label>           Last name:           <input             style={style.input}             type="text"             name="lastName"             onChange={this.onLastNameChange}             onBlur={this.onLastNameBlur}           />           {lastNameError && <div style={style.error}>{lastNameError}</div>}         </label>       </div>       <Greetings firstName={firstName} lastName={lastName} />     </div>   ); } } export default SimpleForm;
      
      





— , firstName



.



«»? — , .



▍ №3:



, , , , , . , , render



. .



, , , . TextField



, .



 import React from 'react' import style from "./style"; const TextField = ({name, onChange, onBlur, error, label}) => ( <div style={style.inputGroup}>   <label>     {label}     <input       style={style.input}       type="text"       name={name}       onChange={onChange}       onBlur={onBlur}     />     {error && <div style={style.error}>{error}</div>}   </label> </div> ); export default TextField;
      
      





, , render



. , , .



SimpleForm



:



 ... import TextField from './TextField'; class SimpleForm extends React.Component { ... render() {   const { firstNameError, firstName, lastName, lastNameError } = this.state;   return (     <div style={style.form}>       <TextField name="firstName"                  label="First name:"                  onChange={this.onFirstNameChange}                  onBlur={this.onFirstNameBlur}                  error={firstNameError} />       <TextField name="lastName"                  label="Last name:"                  onChange={this.onLastNameChange}                  onBlur={this.onLastNameBlur}                  error={lastNameError} />       <Greetings firstName={firstName} lastName={lastName} />     </div>   ); } }
      
      





, . , TextField



. FirstNameField



:



 import React from 'react'; import TextField from './TextField'; const FirstNameField = ({...rest}) => ( <TextField name="firstName"             label="First name:"             {...rest} /> ); export default FirstNameField;
      
      





, . ({...rest})



( rest, ). , , , rest



. , , TextField



, « », spread (, {...rest}



, ). rest



, , TextField



.



, : , FirstNameField



TextField



.



LastNameField



:

:



 ... import FirstNameField from './FirstNameField'; import LastNameField from './LastNameField'; class SimpleForm extends React.Component { ... render() {   const { firstNameError, firstName, lastName, lastNameError } = this.state;   return (     <div style={style.form}>       <FirstNameField onChange={this.onFirstNameChange}                       onBlur={this.onFirstNameBlur}                       error={firstNameError} />       <LastNameField onChange={this.onLastNameChange}                       onBlur={this.onLastNameBlur}                       error={lastNameError} />       <Greetings firstName={firstName} lastName={lastName} />     </div>   ); } }
      
      





.





, , , :







, React- . , , , , . , , , React, , , , UI-.



→ , ,



! , , React-, .






All Articles