Reactチュートリアルパート25:Forms Workshop

Reactトレーニングコースの翻訳の今日の部分では、フォームタスクを完了するように招待されています。



画像



パート1:コースの概要、React、ReactDOM、JSXの人気の理由

パート2:機能コンポーネント

パート3:コンポーネントファイル、プロジェクト構造

パート4:親コンポーネントと子コンポーネント

パート5:TODOアプリケーションの作業の開始、スタイリングの基本

パート6:コースの一部の機能、JSXおよびJavaScriptについて

パート7:インラインスタイル

パート8:TODOアプリケーションの継続的な作業、コンポーネントのプロパティに精通

パート9:コンポーネントのプロパティ

パート10:コンポーネントのプロパティとスタイルの操作に関するワークショップ

パート11:動的マークアップ生成およびマップ配列メソッド

パート12:ワークショップ、TODOアプリケーションの作業の第3段階

パート13:クラスベースのコンポーネント

パート14:クラスベースのコンポーネント、コンポーネントのステータスに関するワークショップ

パート15:コンポーネントヘルスワークショップ

パート16:TODOアプリケーションの作業の第4段階、イベント処理

パート17:TODOアプリケーションの作業の第5段階、コンポーネントの状態の変更

パート18:TODOアプリケーションの作業の6番目の段階

パート19:コンポーネントのライフサイクルメソッド

パート20:条件付きレンダリングの最初のレッスン

パート21:条件付きレンダリングに関する2番目のレッスンとワークショップ

パート22:TODOアプリケーションの作業の第7段階、外部ソースからのデータのダウンロード

パート23:フォームの操作に関する最初のレッスン

パート24:2番目のフォームレッスン

パート25:フォームの操作に関するワークショップ

パート26:アプリケーションアーキテクチャ、コンテナ/コンポーネントパターン

パート27:コースプロジェクト



レッスン43.ワークショップ。 フォームを操作する



オリジナル



▍ジョブ



この実践的なレッスンでは、create-react-appツールを使用して作成された標準プロジェクトのApp.js



ファイルにあるApp



コンポーネントのコードを表示するようにApp.js



ます。 このコードは次のとおりです。



 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {}   }     render() {       return (           <main>               <form>                   <input placeholder="First Name" /><br />                   <input placeholder="Last Name" /><br />                   <input placeholder="Age" /><br />                                     {/*       */}                   <br />                                     {/*          */}                   <br />                                     {/*        */}                   <br />                                     <button>Submit</button>               </form>               <hr />               <h2><font color="#3AC1EF">Entered information:</font></h2>               <p>Your name: {/*    */}</p>               <p>Your age: {/*  */}</p>               <p>Your gender: {/*  */}</p>               <p>Your destination: {/*   */}</p>               <p>                   Your dietary restrictions:                   {/*    */}               </p>           </main>       )   } } export default App
      
      





一般に、タスクは、フォームコントロールでの作業中にユーザーが入力したデータが、このフォームの下のテキストにすぐに表示されるようにすることです。 タスク中に制御コンポーネントのテクノロジーを使用します。 提供されるタスクはこのタスクの適応バージョンであることに注意してください。したがって、作成して構成するように招待されたコントロールの機能をよりよく理解するために、それを確認できます。



コンポーネントが画面に表示されるようになりました。









ブラウザでのアプリケーション



ソリューション



提案された問題の解決策にさまざまな角度からアプローチできます。 まず、必要なものをすべて状態にしてから、コンポーネントのコントロールやその他のメカニズムを構成します。



現時点では、コンポーネントの状態は次のようになります。



 this.state = {   firstName: "",   lastName: "",   age: 0,   gender: "",   destination: "",   dietaryRestrictions: [] }
      
      





プログラムで作業するプロセスでは、たとえば、状態を別の方法で初期化する方が便利であることが判明する可能性があることを考慮する必要があります。 同様のことが発生した場合、状態初期化コードを変更します。 特に、現在、 age



プロパティに書き込まれた数字0によっていくつかの疑問が生じている可能性があります。このプロパティには、ユーザーが入力した年齢が格納されています。 おそらく、空の配列で初期化されたdietaryRestrictions



プロパティで表されるフラグデータストレージシステムを使用する必要があります。



次に、状態の初期化後、制御要素を使用します。 コードにはすでに入力フィールドの説明があるので、それらを使って始めましょう。



これらのコントロールには、これらのフィールドに入力されたデータが保存される状態プロパティの名前と一致するように、 name



属性を設定してname



付ける必要があります。 それらには、状態に保存されているデータに基づいて値が決定されるvalue



属性が必要です。 これらの各フィールドにデータを入力するとき、入力したデータをコンポーネントに渡す必要があります。これにより、それらのコンポーネントにonChange



イベントonChange



が必要になります。 これらすべての考慮事項により、フィールドの説明は次のようになります。



 <input   name="firstName"   value={this.state.firstName}   onChange={this.handleChange}   placeholder="First Name" /> <br /> <input   name="lastName"   value={this.state.lastName}   onChange={this.handleChange}   placeholder="Last Name" /> <br /> <input   name="age"   value={this.state.age}   onChange={this.handleChange}   placeholder="Age" />
      
      





これらのフィールドのonChange



イベントの処理に使用されるメソッドとして、 this.handleChange



はまだ存在していません。 このメソッドを作成します。



 handleChange(event) {   const {name, value} = event.target   this.setState({       [name]: value   }) }
      
      





ここでは、 event.target



オブジェクトからname



value



プロパティを抽出し、それらを使用して対応する状態プロパティを設定します。 現時点では、このようなユニバーサルイベントハンドラーのコードが適していますが、後でフラグを操作するようになったときに、変更を加えます。



コンポーネントコンストラクターで実行されるthis



バインディングを忘れないでください。



 this.handleChange = this.handleChange.bind(this)
      
      





firstName



secondName



、およびage



フィールドに入力されたデータのページの下部で出力を達成するために、対応する<p>



要素を使用して、それらを次の形式にします。



 <p>Your name: {this.state.firstName} {this.state.lastName}</p> <p>Your age: {this.state.age}</p>
      
      





では、得られたものを見てみましょう。









ブラウザでのアプリケーション



ご覧のとおり、年齢を入力するフィールドにはヒントは表示されません。 代わりに、 age



の状態プロパティに設定されているもの、つまり0が表示されます。空のフィールドにヒントが必要です。 stateのage



の値をnull



に置き換えてみましょう。 その後、フォームは本来の外観になりますが、コンソールにage



フィールドに関する次の警告が表示されます。



 Warning: `value` prop on `input` should not be null. Consider using an empty string to clear the component or `undefined` for uncontrolled components
      
      





その結果、 age



状態プロパティの値を空の文字列に置き換えて、状態初期化コードを次の形式にする必要があります。



 this.state = {   firstName: "",   lastName: "",   age: "",   gender: "",   destination: "",   dietaryRestrictions: [] }
      
      





ここでフォームを試してください。 開始直後は、作業の最初と同じように表示されます。つまり、プロンプトはage



フィールドに戻ります。 フィールドに入力すると、入力されたデータがページの下部に表示されます。









ブラウザでのアプリケーション



ご覧のとおり、作業のこの段階では、すべてが期待どおりに機能します。



次に、新しい要素に取り組みます。 フォームで作業する次のステップは、フォームにスイッチを追加することです。



<label>



でスイッチをラップします。これにより、スイッチに署名するだけでなく、この署名、つまり親要素をクリックして選択できるようになります。



スイッチを操作する場合、フラグは、 checked



属性を持つフラグとvalue



属性を持つテキストフィールドの組み合わせのようなものであることを覚えておく価値があります。 スイッチは、各スイッチに同じ名前が割り当てられたグループを形成し、スイッチのchecked



プロパティは、同じグループに属する複数のスイッチをオンにできないように構成された条件に従って設定されます。 onChange



onChange



スイッチのイベントハンドラとしてonChange



ます。



その結果、スイッチ記述コードは次のようになります。



 <label>   <input       type="radio"       name="gender"       value="male"       checked={this.state.gender === "male"}       onChange={this.handleChange}   /> Male </label> <br /> <label>   <input       type="radio"       name="gender"       value="female"       checked={this.state.gender === "female"}       onChange={this.handleChange}   /> Female </label>
      
      





次に、ページの下部にある対応する<p>



要素を次のように処理します。



 <p>Your gender: {this.state.gender}</p>
      
      





その後、フォームをテストできます。 チェックされたプロパティをtrue



に設定するときに実行されるチェックを許可しない状態で値が保存されるため、開始直後は両方のスイッチが選択されていません。 それらのいずれかをクリックすると、対応する値が状態(スイッチのvalue



属性に格納されている)になり、スイッチが選択され、対応するテキストがフォームの下部に表示されます。









ブラウザでのアプリケーション



それでは、コンボボックスで作業しましょう。 彼のワークピースは次のようになります。



 <select>   <option></option>   <option></option>   <option></option>   <option></option> </select>
      
      





このコードは、4つの要素を含むリストボックスを記述することを示しています。



<select>



タグとその<option>



タグにはvalue



属性があります。 ただし、これらの属性には異なる意味があります。 <option>



要素に割り当てられたvalue



は、この要素が選択されたときに対応する状態プロパティがどうあるべきかを示し<option>



。 これらは、ドロップダウンリストにあるべき行です。 私たちの場合、これらは特定の国、たとえば国です。 外観がコード内の他の要素のvalue



プロパティの値に対応するように、名前を小文字で書きましょう。 その後、コンボボックスのコードは次のようになります。



 <select value=>   <option value="germany">Germany</option>   <option value="norway">Norway</option>   <option value="north pole">North Pole</option>   <option value="south pole">South Pole</option> </select>
      
      





<select>



value



属性について説明するvalue



、ここではハードコーディングされた値ではなく、対応する状態プロパティへのリンクが示されます。



 <select value={this.state.destination}>   <option value="germany">Germany</option>   <option value="norway">Norway</option>   <option value="north pole">North Pole</option>   <option value="south pole">South Pole</option> </select>
      
      





フィールドに他の属性を割り当てます。 特に、状態のプロパティの名前に対応する名前、およびonChange



イベントonChange



this.handleChange



です。



 <select   value={this.state.destination}   name="destination"   onChange={this.handleChange} >   <option value="germany">Germany</option>   <option value="norway">Norway</option>   <option value="north pole">North Pole</option>   <option value="south pole">South Pole</option> </select>
      
      





次に、 <p>



要素の説明を構成します。これにより、 destination



フィールドで選択されたものが表示されます。



 <p>Your destination: {this.state.destination}</p>
      
      





今ブラウザでページを見ると、リストの最初の要素がフィールドで自動的に選択されていることがわかりますが、 Your destination:



行のコロンの後に何も表示されないため、これは明らかに状態の更新にはつながりません。









ブラウザでのアプリケーション



germany



値が州に収まるようにするには、コンボボックスを開き、最初に別のものを選択してから、 Germany



選択する必要があります。



多くの場合、リストフィールドのこの機能を考慮するために、リストの最初の要素として、空の値と次のようなテキストを持つ要素のようなものを配置します-- Please Choose a destination --



。 この場合、次のようになります。



 <select   value={this.state.destination}   name="destination"   onChange={this.handleChange} >   <option value="">-- Please Choose a destination --</option>   <option value="germany">Germany</option>   <option value="norway">Norway</option>   <option value="north pole">North Pole</option>   <option value="south pole">South Pole</option> </select>
      
      





コンボボックスを設定するこのオプションに焦点を当てます。



ここで、おそらく、フラグに関連付けられているタスクの最も難しい部分に対処しましょう。 ここでは、フラグを操作するために使用される予定の状態プロパティdietaryRestrictions



が空の配列で初期化されたことをdietaryRestrictions



価値があります。 さて、コントロールの操作に関しては、このフィールドをオブジェクトとして表現した方が良いと感じています。 そのため、配列要素の形式ではなく、わかりやすい名前でこのオブジェクトのプロパティの形式で個々のフラグを表すエンティティを操作する方が便利です。 dietaryRestrictions



状態dietaryRestrictions



で表されるオブジェクトのプロパティには、対応するチェックボックスがクリアされている( false



)かチェックされている( true



)かを示すブール値が含まれます。 これで、ステータス初期化コードは次のようになります。



 this.state = {   firstName: "",   lastName: "",   age: "",   gender: "",   destination: "",   dietaryRestrictions: {       isVegan: false,       isKosher: false,       isLactoseFree: false   } }
      
      





ご覧のとおり、3つのフラグを作成する予定です。 それらはすべて、ページをロードした直後にリセットされます。



コンポーネントによって返されるコードでフラグを記述し、それらを<label>



タグでラップして、属性を設定します。 コードは次のようになります。



 <label>   <input       type="checkbox"       name="isVegan"       onChange={this.handleChange}       checked={this.state.dietaryRestrictions.isVegan}   /> Vegan? </label> <br /> <label>   <input       type="checkbox"       name="isKosher"       onChange={this.handleChange}       checked={this.state.dietaryRestrictions.isKosher}   /> Kosher? </label> <br /> <label>   <input       type="checkbox"       name="isLactoseFree"       onChange={this.handleChange}       checked={this.state.dietaryRestrictions.isLactoseFree}   /> Lactose Free? </label>
      
      





dietaryRestrictions



オブジェクトのプロパティの名前はフラグ名としてthis.state.dietaryRestrictions.isSomething



れ、 this.state.dietaryRestrictions.isSomething



という形式の構成this.state.dietaryRestrictions.isSomething



checked



属性の値としてthis.state.dietaryRestrictions.isSomething



れました。



既存のonChange



this.handleChange



イベントハンドラーとして指定されていますが、プログラムが正しく機能するようにプログラムに変更を加える必要があることに注意してください。



アプリケーションを見てください。









ブラウザでのアプリケーション



ご覧のとおり、ページ上のフラグは表示されますが、コンポーネントには適切な動作を保証するために必要なすべてのメカニズムが含まれていません。 イベントハンドラを扱いましょう。



ここで、フラグを操作するには、既に抽出されたものに加えて、 event.target



オブジェクトからtype



checked



プロパティを抽出する必要がありchecked



。 1つ目は要素のタイプをチェックするために必要です(フラグはcheckbox



行で表されるタイプです)、2つ目はチェックボックスがチェックされているかチェックされていないかを調べることです。 ユーザーがフラグを操作した後にハンドラーが呼び出されたことが判明した場合、特別な状態設定手順を使用します。 以前と同じ方法で他のコントロールのイベントを処理します。



状態を更新する場合、Reactはかなりインテリジェントなシステムであり、状態の一部のみが更新されると、変更されていないものと変更されたものが新しい状態で自動的に結合されることに留意してください。 ただし、状態プロパティの値であるオブジェクトのプロパティを使用した作業も実行されるかどうかはわかりません。 これを確認するには、 handleChange



コードを次のフォームにhandleChange



ます。 ここでは、 dietaryRestrictions



オブジェクトのプロパティは一度に1つずつ変更できるという前提から進みます。



 handleChange(event) {   const {name, value, type, checked} = event.target   type === "checkbox" ?       this.setState({           dietaryRestrictions: {               [name]: checked           }       })   :   this.setState({       [name]: value   }) }
      
      





ブラウザでアプリケーションページを開くと、ダウンロード直後にすべてが正常に表示されます。たとえば、[ First Name



フィールドに名前を入力しようとすると、すべてが以前と同様に機能しますが、チェックボックスのいずれかをインストールしようとすると、次の警告が発行されます:

警告:コンポーネントは、チェックボックスタイプの制御入力を非制御に変更しています。 入力要素は、制御された状態から制御されていない状態(またはその逆)に切り替えないでください。 コンポーネントの寿命の間、制御された入力要素を使用するか、制御されていない入力要素を使用するかを決定します。 詳細: fb.me/react-controlled-components


dietaryRestrictions



オブジェクトの内容を正しく更新するために、 setState



関数フォームを使用して状態の新しいバージョンを自分で作成できます。 多数のフラグを管理する必要がある場合は、おそらく管理しているでしょう。 しかし、ここでは別の方法で行います。 つまり、 dietaryRestrictions



オブジェクトdietaryRestrictions



プロパティのプロパティを作成し、このオブジェクトをdietaryRestrictions



ます。



 this.state = {   firstName: "",   lastName: "",   age: "",   gender: "",   destination: "",   isVegan: false,   isKosher: false,   isLactoseFree: false }
      
      





ここで、 dietaryRestrictions



て、フラグの属性の設定を変更します。



 <label>   <input       type="checkbox"       name="isVegan"       onChange={this.handleChange}       checked={this.state.isVegan}   /> Vegan? </label> <br /> <label>   <input       type="checkbox"       name="isKosher"       onChange={this.handleChange}       checked={this.state.isKosher}   /> Kosher? </label> <br /> <label>   <input       type="checkbox"       name="isLactoseFree"       onChange={this.handleChange}       checked={this.state.isLactoseFree}   /> Lactose Free? </label>
      
      





最後に、ユーザーが指定した食事制限に関する情報を表示する要素のコードを編集します。



 <p>Your dietary restrictions:</p> <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p> <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p> <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p>
      
      





その後、アプリケーションの正常性を確認します。









ブラウザでのアプリケーション



どうやら、すべてが期待どおりに動作します。



App



コンポーネントの完全なコードは次のとおりです。



 import React, {Component} from "react" class App extends Component {   constructor() {       super()       this.state = {           firstName: "",           lastName: "",           age: "",           gender: "",           destination: "",           isVegan: false,           isKosher: false,           isLactoseFree: false       }       this.handleChange = this.handleChange.bind(this)   }     handleChange(event) {       const {name, value, type, checked} = event.target       type === "checkbox" ?           this.setState({               [name]: checked           })       :       this.setState({           [name]: value       })   }     render() {       return (           <main>               <form>                   <input                       name="firstName"                       value={this.state.firstName}                       onChange={this.handleChange}                       placeholder="First Name"                   />                   <br />                                     <input                       name="lastName"                       value={this.state.lastName}                       onChange={this.handleChange}                       placeholder="Last Name"                   />                   <br />                                     <input                       name="age"                       value={this.state.age}                       onChange={this.handleChange}                       placeholder="Age"                   />                   <br />                                     <label>                       <input                           type="radio"                           name="gender"                           value="male"                           checked={this.state.gender === "male"}                           onChange={this.handleChange}                       /> Male                   </label>                                     <br />                                     <label>                       <input                           type="radio"                           name="gender"                           value="female"                           checked={this.state.gender === "female"}                           onChange={this.handleChange}                       /> Female                   </label>                                     <br />                                     <select                       value={this.state.destination}                       name="destination"                       onChange={this.handleChange}                   >                       <option value="">-- Please Choose a destination --</option>                       <option value="germany">Germany</option>                       <option value="norway">Norway</option>                       <option value="north pole">North Pole</option>                       <option value="south pole">South Pole</option>                   </select>                                     <br />                                     <label>                       <input                           type="checkbox"                           name="isVegan"                           onChange={this.handleChange}                           checked={this.state.isVegan}                       /> Vegan?                   </label>                   <br />                                     <label>                       <input                           type="checkbox"                           name="isKosher"                           onChange={this.handleChange}                           checked={this.state.isKosher}                       /> Kosher?                   </label>                   <br />                                     <label>                       <input                           type="checkbox"                           name="isLactoseFree"                           onChange={this.handleChange}                           checked={this.state.isLactoseFree}                       /> Lactose Free?                   </label>                   <br />                                     <button>Submit</button>               </form>               <hr />               <h2><font color="#3AC1EF">Entered information:</font></h2>               <p>Your name: {this.state.firstName} {this.state.lastName}</p>               <p>Your age: {this.state.age}</p>               <p>Your gender: {this.state.gender}</p>               <p>Your destination: {this.state.destination}</p>               <p>Your dietary restrictions:</p>                             <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p>               <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p>               <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p>                         </main>       )   } } export default App
      
      





まとめ



今日、フォームに関する実践的な作業を完了しました。 その後、前のクラスで学んだことを繰り返しました。新しいことを学んだことを願っています。 次回は、Reactアプリケーションのアーキテクチャについて説明します。



親愛なる読者! この実践的な作業を完了することは困難でしたか?






All Articles