⊗jsrtPmCpMVS 90 of 112 menu

Reactにおける子コンポーネントのステートを介した動作モード

製品の配列が次のようになっているとします:

const initProds = [ {id: id(), name: 'prod1', cost: 'cost1', catg: 'catg1'}, {id: id(), name: 'prod2', cost: 'cost2', catg: 'catg2'}, {id: id(), name: 'prod3', cost: 'cost3', catg: 'catg3'}, ];

これらの製品をHTMLテーブルとして表示してみましょう。 また、テーブルの任意のセルをクリックすると、そのセルに編集用の入力フィールドが表示されるようにします。 この問題を解決するために、3つのコンポーネントを作成します。

Productsコンポーネントは製品のステートを保持し、 製品を表示するためにProductコンポーネントを使用します。 Productコンポーネントは、今度は特定の製品フィールド(名前、価格、カテゴリ)を表示するために ProductFieldコンポーネントを使用します。

ProductFieldコンポーネントは、 フィールドのテキストを表示するか、その編集用の入力フィールドを表示します。 このとき、編集モードまたは表示モードはこのコンポーネント自身のステートによって制御されるようにします。

つまり、モードを親のステートに保存しません。 親に保存すると非常に不便になります。なぜなら、製品の各フィールドごとにモードを指定する必要があり、 ステートが次のようなものになってしまうからです:

const initProds = [ [ {field: 'name', value: 'prod1', isEdit: false}, {field: 'cost', value: 'cost1', isEdit: false}, {field: 'catg', value: 'catg1', isEdit: false}, ], [ {field: 'name', value: 'prod2', isEdit: false}, {field: 'cost', value: 'cost2', isEdit: false}, {field: 'catg', value: 'catg2', isEdit: false}, ], [ {field: 'name', value: 'prod3', isEdit: false}, {field: 'cost', value: 'cost3', isEdit: false}, {field: 'catg', value: 'catg3', isEdit: false}, ], ]

しかし、私たちはそのようなステートを作らず、元のステートをそのままにします。 単に、各ProductFieldコンポーネントのインスタンスが、自身のステートを使って、 編集モードか表示モードかを制御するようにします。

これにより、親コンポーネントがデータのステートを保持し、 孫コンポーネントがそのデータをpropsを通じて受け取りながら、 自身のモードを変更するための独自のステートを持つ、という構造になります。

では、説明した内容を実装してみましょう。

Productsコンポーネント

function Products() { const [prods, setProds] = useState(initProds); function changeField(id, field, event) { setProds(prods.map(prod => { if (prod.id === id) { prod[field] = event.target.value; } return prod; })); } const rows = prods.map(prod => { return <Product key ={prod.id} id ={prod.id} name={prod.name} cost={prod.cost} catg={prod.catg} changeField={changeField} />; }); return <div> <table> <tbody> {rows} </tbody> </table> </div>; }

Productコンポーネント

function Product({ id, name, cost, catg, changeField }) { return <tr> <ProductField id={id} text={name} type="name" changeField={changeField} /> <ProductField id={id} text={cost} type="cost" changeField={changeField} /> <ProductField id={id} text={catg} type="catg" changeField={changeField} /> </tr>; }

ProductFieldコンポーネント

function ProductField({ id, text, type, changeField }) { const [isEdit, setIsEdit] = useState(false); return <td> { isEdit ? <input value={text} onChange={event => changeField(id, type, event)} onBlur={() => setIsEdit(false)} /> : <span onClick={() => setIsEdit(true)}>{text}</span> } </td>; }

実践タスク

これまでのレッスンで作成したUsersコンポーネントとUserコンポーネントに対しても、 同様の操作を実装してみてください。

日本語
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesiaItalianoქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
当サイトでは、サイトの動作、分析、パーソナライゼーションのためにクッキーを使用しています。 データ処理はプライバシーポリシーに従って行われます。
すべて受け入れる 設定 拒否