逆データ フローについて


This blog requires some base knowledge of Props and State in React. You can read up on both here.



逆データ フローとは



ここまでで、データが流れる方法は親コンポーネントから子コンポーネントへの prop の形であることを学びました.逆データ フローでは、そのフローを切り替えて、データが子コンポーネントから親コンポーネントに渡されるようにします.

それはどのように機能しますか?



子コンポーネントがデータを渡すには、親がコールバック関数を子に渡す必要があります.コールバック関数は、prop として子に渡されます (通常のデータ フローと同様).親コンポーネントで関数を定義することにより、子でそれを呼び出すことができ、親は渡されたデータにアクセスできます.

概念化



これは React の非常に重要な概念であり、いつでも使用できるものです.コツをつかめば、コンポーネントの再利用、よりクリーンなコード、コンポーネントのレンダリング、イベントの支援に使用できます.実際にコードを書いてどのように機能するかを示す前に、多くの人がコード以外でよく知っている状況を使用して、非常に単純化した概念に分解してみましょう.この図を見て、以下で逆データ フローを説明するのにどのように役立つかを説明します.



私たちには親 (お母さん) と彼女の 2 人の子供 (ボブとサリー) がいます.お母さんがボビーにおもちゃ (状態データ) を渡すと、ボビーはそれらのおもちゃにアクセスできるようになりました.ボブの妹もおもちゃを手に入れたいので、ボブに頼みます. Bob はノーと言います.Children は別の子コンポーネントにデータを渡すことができないため、これは重要な注意事項です.最初に親を通過し、次に子に通過する必要があります.サリーはお母さんにおもちゃをいくつか頼むと、お母さんはすべてのおもちゃ (データ) を持っているボブのところへ行きます.彼女は手を差し出し (コールバック関数)、ボブは彼女におもちゃを渡します (コールバックを呼び出し、データを親に戻します).お母さんはおもちゃを手に入れ、それを持って別のことをすることができますが、代わりにサリーに渡します (新しい状態を設定します).階層構造に入れると、次のようになります.



コードで見る



データがどのように渡されるかを視覚化したところで、コードの例を見てみましょう.

子コンポーネントとして GroceryItemsList と GroceryCart を持つ App コンポーネント (親) から始めます. State を App コンポーネント (groceryItems の配列) に保持し、それを GroceryItemsList に渡し、それを繰り返し処理して、個々の食料品のリスト (オブジェクト) を作成します.私たちの目標は、GroceryItem をクリックして GroceryCart コンポーネントに追加できるようにすることです.これはデータ フローの視覚化です.



App コンポーネントでコールバック関数を作成し、それを小道具として GroceryItemsList に渡すことから始めましょう.

function onGroceryItemClick(item) { //this is our callback function
 console.log("We are adding this to GroceryCart", item) //making sure it passes it down and back up smoothly
}
  return (
    <div> 
        <GroceryItemsList 
            onGroceryItemClick={onGroceryItemClick} //we are passing our callback function as a prop
            groceries={groceries} 
        />
        <GroceryCart />
    </div>
  )
}
export default App;


次に、GroceryItemsList に移動し、小道具を分解して、それを GroceryItem に渡す必要があります.注: onGroceryItemClick コールバック関数を prop として渡していますが、何をするのかを明確にするために handleGroceryItemClick という名前を付けています.

function GroceryItemsList({onGroceryItemClick, groceries}) {
   const groceryItem = groceries.map((groceryObj) => {
      <GroceryItemCard
         key={groceryObj.id}
         groceryItem={groceryObj}
         handleGroceryItemClick = {onGroceryItemClick} //passing callback down another child level
      />
));
  return(
    <div> 
       {groceryItem}
    </div>


GroceryItemCard で、そのコールバック prop を取得し、それを呼び出すために必要なデータを提供します.

function GroceryItemCard({groceryItem, handleGroceryItemClick}) {
   const {name, description, price, image} = groceryItem

   return(
      <div onClick={()=> handleGroceryItemClick(groceryItem)}> //This says 'when we click on the GroceryItemCard we are going to invoke our function and send it a groceryItem (an object)
        <img src={image} alt={name} />
        <h5>{name}</h5>
        <p>{description}</p>
        <p>{price}</p>
      </div>



GroceryItemCard をクリックすると、console.logging であることがわかります.

We are adding this to GroceryCart
 {id:1, item:'Milk', price:'$3.99', brand:'Lucerne', image:'https://media.istockphoto.com/photos/kefir-milk-or-turkish-ayran-drink-are-poured-into-a-glass-cup-from-a-picture-id1198789194?b=1&k=20&m=1198789194&s=170667a&w=0&h=f85XhCzCWQhdFn0LaRckyOkJui88sYNoctN9zEmS4y0=' }


コールバック関数を正常に渡し、それを子から親に呼び出しました!それが逆データフローです!!

親に GroceryItem オブジェクトがあるので、GroceryCart の状態をそのオブジェクトに設定してレンダリングできます.

function onGroceryItemClick(item) { //this is our callback function
 setGroceryCart([...cart, item]) //Adding item to our GroceryCart by setting its state
}
  return (
    <div> 
        <GroceryItemsList 
            onGroceryItemClick={onGroceryItemClick} 
            groceries={groceries} 
        />
        <GroceryCart />
    </div>
  )
}
export default App;




では、逆データ フローについて説明します.私の経験では、逆データ フローはイベント (onChange、onClick など (特に検索バーやあらゆる種類のフィルター)) に対して非常にうまく機能します.これは、コンポーネントの再利用性と、State をライブラリ内のどこに配置するかを整理するのに役立ちます.理解するのは難しい概念ですが、小道具に適切な名前を付けて、上から下、親から子へと作業することで、何が受け継がれているかを追跡できるようになりました.


参考文献:
https://reactjs.org/docs/thinking-in-react.html