最近、Reactを初めて触ったのですが、ほかの言語を学んでいるとpropsの扱いがかなりややこしかったので、備忘録としてまとめます。
例えば、こんなオブジェクトを用意します。
const RecipeInfo = {
// 料理名
title : '',
//コメント
comment : '',
//材料
ingredients:[
],
//手順
procedure:[
],
}
const [recipe, setRecipe] = useState(RecipeInfo);
これは、初期値RecipeInfoをrecipeにセットします。さらにrecipeの値を更新したい場合は、setRecipeという関数で更新するというuseStateになります。
次に子要素にこれらの情報を引き継ぎます。下記のような記載になります。
{/* 料理名 */}
<RecipeTitle recipe = {recipe} ,setRecipe = {setRecipe}/>
{/* コメント */}
<RecipeComment recipe = {recipe} ,setRecipe = {setRecipe}/>
{/* 材料 */}
<Ingredient recipe = {recipe} ,setRecipe = {setRecipe}/>
細かい子要素の中身は割愛しますが、RecipeTitle、RecipeComment,Ingredientの3つの子要素に親要素が持っているrecipeとsetRecipeの情報を渡します。下記のようなイメージです。
次に子要素側でpropsを使って呼び出します。RecipeTitleの場合は、以下の通りになります。
function RecipeTitle(props) {
//処理を書く
}
このときに、recipeのそれぞれの項目とセット関数を呼び出すにはどのように処理をかけばいいでしょうか?
答えは次の通りです。
function RecipeTitle(props) {
props.recipe.title
props.recipe.comment
props.recipe.ingredient.プロパティ名
props.recipe.procedure.プロパティ名
props.setRecipe(更新する値)
}
となります。ややこしいので、一回整理します。
JavaやC言語などは関数の呼び出し元と呼び出し先が1:1で対応します。
イメージは次のようになります。
図のように呼び出し先の引数が2個なら、呼び出し元でも引数は2個、呼び出し先の引数が3個なら、呼び出し元でも引数は3個のように呼び出し先と呼び出し先で1:1で対応しているのが分かります。
対して、Reactのpropsのイメージは次のようになります。
先ほどは1:1であったのに対して、今度は1:多の関係になっています。
呼び出し元で引数を追加しても呼び出し先はソースを変更する必要がありません。
そのため、呼び出し先で値を参照する場合は、
・propsの中にあるレシピの中にあるタイトル(props.recipe.title)
・propsの中にあるレシピの中にある材料の中にある〇〇(props.recipe.ingredient.〇〇)
・propsの中にあるセット関数(props.setRecipe(〇〇))
のようにアクセスする必要があります。イメージはこんな感じです。
JavaやCであれば、一番上の階層のpropsがありません。recipe,setRecipeの階層からスタートします。
他の言語を経験している人だからこそ陥りそうな罠でしたので、あえて記事にまとめました。
参考にしていただければ幸いです。
と言ってもuseContextを使えば、わざわざ子要素に引き継ぐなんて考えなくてよいので、これらのことを気にする必要はありません。
useContextを使うことを推奨します。
それでは