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-, .

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


All Articles