[{"data":1,"prerenderedAt":730},["ShallowReactive",2],{"\u002Fother_memorandum\u002Freact":3},{"id":4,"title":5,"body":6,"date":720,"description":721,"draft":722,"extension":723,"meta":724,"navigation":725,"path":726,"seo":727,"stem":728,"__hash__":729},"blog\u002F900.other_memorandum\u002F09.react.md","Reactについて",{"type":7,"value":8,"toc":699},"minimark",[9,14,18,46,116,120,137,141,165,169,183,187,199,203,251,254,282,349,353,376,380,398,430,434,439,474,482,500,503,528,531,534,545,549,556,593,597,600,630,633,636,671,684,687,696],[10,11,13],"h2",{"id":12},"reactの基本ルール","Reactの基本ルール",[15,16,17],"h3",{"id":17},"パーツ設計",[19,20,21,30,37,40,43],"ul",{},[22,23,24,25,29],"li",{},"パーツ（",[26,27,28],"code",{},"Component","）を組み合わせて画面を構築する。",[22,31,32,33,36],{},"値（",[26,34,35],{},"state","）をもとにDOMを生成する。",[22,38,39],{},"JSXでHTMLを記述する。",[22,41,42],{},"デザイン（CSS）そのものはReact自体では設計しない。",[22,44,45],{},"参考ページでは、初期表示の実装を以下のように行っている。",[47,48,53],"pre",{"className":49,"code":50,"language":51,"meta":52,"style":52},"language-javascript shiki shiki-themes github-light","ReactDOM.render(\n  \u003CMyComponent \u002F>,\n  \u002F* Reactが生成したコードを#mainに書き出す *\u002F\n  document.getElementById('main') \n);\n\n","javascript","",[26,54,55,71,84,91,110],{"__ignoreMap":52},[56,57,60,64,68],"span",{"class":58,"line":59},"line",1,[56,61,63],{"class":62},"sgsFI","ReactDOM.",[56,65,67],{"class":66},"s7eDp","render",[56,69,70],{"class":62},"(\n",[56,72,74,77,81],{"class":58,"line":73},2,[56,75,76],{"class":62},"  \u003C",[56,78,80],{"class":79},"sYu0t","MyComponent",[56,82,83],{"class":62}," \u002F>,\n",[56,85,87],{"class":58,"line":86},3,[56,88,90],{"class":89},"sAwPA","  \u002F* Reactが生成したコードを#mainに書き出す *\u002F\n",[56,92,94,97,100,103,107],{"class":58,"line":93},4,[56,95,96],{"class":62},"  document.",[56,98,99],{"class":66},"getElementById",[56,101,102],{"class":62},"(",[56,104,106],{"class":105},"sYBdl","'main'",[56,108,109],{"class":62},") \n",[56,111,113],{"class":58,"line":112},5,[56,114,115],{"class":62},");\n",[117,118,119],"p",{},"上記は、現代のコンポーネント単位の開発においては以下のようにエクスポートすることでも実現できる。",[47,121,123],{"className":49,"code":122,"language":51,"meta":52,"style":52},"export default App;\n\n",[26,124,125],{"__ignoreMap":52},[56,126,127,131,134],{"class":58,"line":59},[56,128,130],{"class":129},"sD7c4","export",[56,132,133],{"class":129}," default",[56,135,136],{"class":62}," App;\n",[10,138,140],{"id":139},"reactの実装基本","Reactの実装基本",[19,142,143,153,159],{},[22,144,145,148,149,152],{},[26,146,147],{},"React.Component"," を継承（",[26,150,151],{},"extends","）して、コンポーネントと呼ばれる「パーツ」を実装する。",[22,154,155,158],{},[26,156,157],{},"extends React.Component"," はクラスコンポーネントにおける決まり文句だ。",[22,160,161,164],{},[26,162,163],{},"render()"," の返り値は、ルートとして1つのDOM（1つの親要素）しか設定できない。",[15,166,168],{"id":167},"stateを使う","Stateを使う",[19,170,171,177],{},[22,172,173,176],{},[26,174,175],{},"State"," はコンポーネント自身が管理する値の集まりだ。",[22,178,179,180,182],{},"Reactは ",[26,181,175],{}," の変化によって表示を動的に変化させることがメイン機能となる。",[15,184,186],{"id":185},"propsを使う","Propsを使う",[19,188,189,196],{},[22,190,191,192,195],{},"呼び出し元から ",[26,193,194],{},"attribute","（属性）経由で値を渡してもらうことができる。",[22,197,198],{},"値だけでなく、メソッド（関数）を渡すことも可能だ。",[15,200,202],{"id":201},"jsxタグ","JSXタグ",[19,204,205,208,211,214,224,227,230,241,248],{},[22,206,207],{},"通常のHTMLタグとは違った概念である。",[22,209,210],{},"JSXタグには、Reactで定義したクラス（コンポーネント）をそのまま使用することができる。",[22,212,213],{},"JSXタグは頭文字を大文字にする必要がある（小文字のままだと通常のHTMLタグと誤認されるため）。",[22,215,216,217,219,220,223],{},"JSXタグは ",[26,218,194],{}," を使うことで、 ",[26,221,222],{},"props"," として子に値を渡せる。",[22,225,226],{},"値だけでなく関数も渡すことが可能だ。",[22,228,229],{},"関数を渡せるため、部品コンポーネントから画面（親）コンポーネントに処理を委任させる（逆方向のデータフローを実現する）こともできる。",[22,231,232,233,236,237,240],{},"クラス名は ",[26,234,235],{},"class"," ではなく、 ",[26,238,239],{},"className"," で指定する。",[22,242,243,244,247],{},"JSXタグのコンポーネント内に別のJSXタグや要素を記述すれば、親のコンポーネントから ",[26,245,246],{},"props.children"," でその子要素を参照できる。",[22,249,250],{},"属性をスプレッド構文などでまとめて渡すこともできるが、そのコンポーネントが何の値を使うかを明示できた方が良いため、一括で丸ごと渡す手法はあまり良くないというのが個人的な所感だ。",[15,252,253],{"id":253},"イベント",[19,255,256,267],{},[22,257,258,259,262,263,266],{},"クリックイベント（",[26,260,261],{},"onClick"," など）にアロー関数（",[26,264,265],{},"() => fetch()","）を使わず直接関数を記述する場合、括弧の有無などを間違えると画面表示（レンダリング）時に処理内容が評価・実行されてしまうため注意が必要だ。",[22,268,269,270,273,274,277,278,281],{},"ループ処理によるリスト表示の際は、 ",[26,271,272],{},"key-value"," で定義した ",[26,275,276],{},"items"," を ",[26,279,280],{},"map"," 関数でループさせ、1つずつ要素を生成して親コンポーネントに返す。",[47,283,285],{"className":49,"code":284,"language":51,"meta":52,"style":52},"return items.map((_item, _key) => {\n    return(\u003Cli key={_key}>{_item.value}\u003C\u002Fli>)\n})\n\n",[26,286,287,319,344],{"__ignoreMap":52},[56,288,289,292,295,297,300,304,307,310,313,316],{"class":58,"line":59},[56,290,291],{"class":129},"return",[56,293,294],{"class":62}," items.",[56,296,280],{"class":66},[56,298,299],{"class":62},"((",[56,301,303],{"class":302},"sqxcx","_item",[56,305,306],{"class":62},", ",[56,308,309],{"class":302},"_key",[56,311,312],{"class":62},") ",[56,314,315],{"class":129},"=>",[56,317,318],{"class":62}," {\n",[56,320,321,324,327,330,333,336,339,341],{"class":58,"line":73},[56,322,323],{"class":129},"    return",[56,325,326],{"class":62},"(\u003C",[56,328,22],{"class":329},"shJU0",[56,331,332],{"class":66}," key",[56,334,335],{"class":129},"=",[56,337,338],{"class":62},"{_key}>{_item.value}\u003C\u002F",[56,340,22],{"class":329},[56,342,343],{"class":62},">)\n",[56,345,346],{"class":58,"line":86},[56,347,348],{"class":62},"})\n",[15,350,352],{"id":351},"cssによるデザイン適用","CSSによるデザイン適用",[19,354,355,358,364,367],{},[22,356,357],{},"React自体にはデザインに関する固有の機能はない。",[22,359,360,363],{},[26,361,362],{},"CSS in JS"," という考え方があり、デザインもJSに含めて管理する形が主流になる可能性がある。",[22,365,366],{},"ライブラリの読み込みとCSSの読み込みを別々に記述するのは面倒であるため、1つで済めば非常に楽だ。",[22,368,369,372,373,375],{},[26,370,371],{},"style"," オブジェクトを定義し、HTMLタグを記述する際にそのオブジェクトを ",[26,374,371],{}," 属性に渡すことで、インラインスタイルとしてレイアウトを管理しやすくできる。",[15,377,379],{"id":378},"routeに値を持つコンポーネントを渡す","Routeに値を持つコンポーネントを渡す",[19,381,382,395],{},[22,383,384,387,388,391,392,394],{},[26,385,386],{},"react-router","（旧バージョン）等において、ルートに値を保持したコンポーネントを渡す際は、 ",[26,389,390],{},"component"," 属性ではなく ",[26,393,67],{}," 属性を使うことで指定できる。",[22,396,397],{},"別ページへの遷移は以下のように記述する。",[47,399,403],{"className":400,"code":401,"language":402,"meta":52,"style":52},"language-html shiki shiki-themes github-light","\u003CLink to=\"\u002F\">Home\u003C\u002FLink>\n\n","html",[26,404,405],{"__ignoreMap":52},[56,406,407,410,413,416,418,421,424,427],{"class":58,"line":59},[56,408,409],{"class":62},"\u003C",[56,411,412],{"class":329},"Link",[56,414,415],{"class":66}," to",[56,417,335],{"class":62},[56,419,420],{"class":105},"\"\u002F\"",[56,422,423],{"class":62},">Home\u003C\u002F",[56,425,412],{"class":426},"sB1qb",[56,428,429],{"class":62},">\n",[15,431,433],{"id":432},"パラメータを含むurlを制御する","パラメータを含むURLを制御する",[19,435,436],{},[22,437,438],{},"URLにパラメータを持たせたいときは、以下のようなルーティング設定を行う。",[47,440,442],{"className":400,"code":441,"language":402,"meta":52,"style":52},"\u003CRoute component={EditPage} path=\"\u002Fedit\u002F:id\">\u003C\u002FRoute>\n\n",[26,443,444],{"__ignoreMap":52},[56,445,446,448,451,454,456,459,462,464,467,470,472],{"class":58,"line":59},[56,447,409],{"class":62},[56,449,450],{"class":426},"Route",[56,452,453],{"class":66}," component",[56,455,335],{"class":62},[56,457,458],{"class":105},"{EditPage}",[56,460,461],{"class":66}," path",[56,463,335],{"class":62},[56,465,466],{"class":105},"\"\u002Fedit\u002F:id\"",[56,468,469],{"class":62},">\u003C\u002F",[56,471,450],{"class":426},[56,473,429],{"class":62},[19,475,476],{},[22,477,478,479,481],{},"上記を設定すると、遷移先のコンポーネントの ",[26,480,222],{}," に値が注入されるため、以下のように参照して利用する。",[47,483,485],{"className":400,"code":484,"language":402,"meta":52,"style":52},"\u003Cp>ID:{props.match.params.id}\u003C\u002Fp>\n\n",[26,486,487],{"__ignoreMap":52},[56,488,489,491,493,496,498],{"class":58,"line":59},[56,490,409],{"class":62},[56,492,117],{"class":329},[56,494,495],{"class":62},">ID:{props.match.params.id}\u003C\u002F",[56,497,117],{"class":329},[56,499,429],{"class":62},[15,501,502],{"id":502},"参考",[19,504,505,514,521],{},[22,506,507],{},[508,509,513],"a",{"href":510,"rel":511},"https:\u002F\u002Fqiita.com\u002Ftomipetit\u002Fitems\u002F6563eacd88e63bda5de3",[512],"nofollow","React初心者のまとめ（基本編：1\u002F3） - Qiita",[22,515,516],{},[508,517,520],{"href":518,"rel":519},"https:\u002F\u002Fqiita.com\u002Ftomipetit\u002Fitems\u002Fcdd319d8fce8bdb829d0",[512],"React初心者のまとめ（基本編：2\u002F3） - Qiita",[22,522,523],{},[508,524,527],{"href":525,"rel":526},"https:\u002F\u002Fqiita.com\u002Ftomipetit\u002Fitems\u002F975eceda3d07b152547c",[512],"React初心者のまとめ（基本編：3\u002F3） - Qiita",[10,529,530],{"id":530},"画面遷移先にパラメータを送る",[117,532,533],{},"必要な実装は以下の3点。",[19,535,536,539,542],{},[22,537,538],{},"クリックした時の遷移処理（メソッド定義）",[22,540,541],{},"クリックした時の遷移処理（JSX側でのコール）",[22,543,544],{},"ルーティングの設定",[15,546,548],{"id":547},"クリックした時の遷移処理1","クリックした時の遷移処理(1)",[117,550,551,552,555],{},"今回は、クリックしたら ",[26,553,554],{},"\u002Fsecondpage"," のページに遷移するように実装する。",[47,557,559],{"className":49,"code":558,"language":51,"meta":52,"style":52},"handleClick() {\n  this.props.history.push('\u002Fsecondpage')\n}\n\n",[26,560,561,569,588],{"__ignoreMap":52},[56,562,563,566],{"class":58,"line":59},[56,564,565],{"class":66},"handleClick",[56,567,568],{"class":62},"() {\n",[56,570,571,574,577,580,582,585],{"class":58,"line":73},[56,572,573],{"class":79},"  this",[56,575,576],{"class":62},".props.history.",[56,578,579],{"class":66},"push",[56,581,102],{"class":62},[56,583,584],{"class":105},"'\u002Fsecondpage'",[56,586,587],{"class":62},")\n",[56,589,590],{"class":58,"line":86},[56,591,592],{"class":62},"}\n",[15,594,596],{"id":595},"クリックした時の遷移処理2","クリックした時の遷移処理(2)",[117,598,599],{},"実際にリンク（ボタン）をクリックした際に、画面遷移させるメソッドをコールする。",[47,601,603],{"className":400,"code":602,"language":402,"meta":52,"style":52},"\u003Cbutton onClick={() => this.handleClick()}>画面遷移\u003C\u002Fbutton>\n\n",[26,604,605],{"__ignoreMap":52},[56,606,607,609,612,615,617,620,623,626,628],{"class":58,"line":59},[56,608,409],{"class":62},[56,610,611],{"class":329},"button",[56,613,614],{"class":66}," onClick",[56,616,335],{"class":62},[56,618,619],{"class":105},"{()",[56,621,622],{"class":426}," =",[56,624,625],{"class":62},"> this.handleClick()}>画面遷移\u003C\u002F",[56,627,611],{"class":329},[56,629,429],{"class":62},[15,631,632],{"id":632},"ルーティングの実装",[117,634,635],{},"画面遷移を受け付けるためにルーティングを設定する。以下の通り。",[47,637,639],{"className":400,"code":638,"language":402,"meta":52,"style":52},"\u003CRoute exact={true} path='\u002Fsecondpage' component={SecondPage} \u002F>\n\n",[26,640,641],{"__ignoreMap":52},[56,642,643,645,647,650,652,655,657,659,661,663,665,668],{"class":58,"line":59},[56,644,409],{"class":62},[56,646,450],{"class":426},[56,648,649],{"class":66}," exact",[56,651,335],{"class":62},[56,653,654],{"class":105},"{true}",[56,656,461],{"class":66},[56,658,335],{"class":62},[56,660,584],{"class":105},[56,662,453],{"class":66},[56,664,335],{"class":62},[56,666,667],{"class":105},"{SecondPage}",[56,669,670],{"class":62}," \u002F>\n",[117,672,673,674,677,678,680,681,683],{},"ルーティングの実装は上から順番にマッチング処理が行われる。\nそのため、ルート ",[26,675,676],{},"\u002F"," の設定を一番下にしておかないと、 ",[26,679,554],{}," に遷移しようとしてもルート ",[26,682,676],{}," のページが誤って表示されてしまうケースがあるため注意が必要。",[15,685,502],{"id":686},"参考-1",[19,688,689],{},[22,690,691],{},[508,692,695],{"href":693,"rel":694},"https:\u002F\u002Fqiita.com\u002Foda3104\u002Fitems\u002Fde5489cd97ba674cbee5",[512],"Reactで画面遷移先に値を送る - Qiita",[371,697,698],{},"html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sB1qb, html code.shiki .sB1qb{--shiki-default:#B31D28;--shiki-default-font-style:italic}",{"title":52,"searchDepth":73,"depth":73,"links":700},[701,704,714],{"id":12,"depth":73,"text":13,"children":702},[703],{"id":17,"depth":86,"text":17},{"id":139,"depth":73,"text":140,"children":705},[706,707,708,709,710,711,712,713],{"id":167,"depth":86,"text":168},{"id":185,"depth":86,"text":186},{"id":201,"depth":86,"text":202},{"id":253,"depth":86,"text":253},{"id":351,"depth":86,"text":352},{"id":378,"depth":86,"text":379},{"id":432,"depth":86,"text":433},{"id":502,"depth":86,"text":502},{"id":530,"depth":73,"text":530,"children":715},[716,717,718,719],{"id":547,"depth":86,"text":548},{"id":595,"depth":86,"text":596},{"id":632,"depth":86,"text":632},{"id":686,"depth":86,"text":502},"2026-06-14T07:00:00+09:00","Reactの備忘録です。",false,"md",{},true,"\u002Fother_memorandum\u002Freact",{"title":5,"description":721},"900.other_memorandum\u002F09.react","q8pp22ndlNqBCvc8fR7Rpw591b87WezvYQiibIhnf54",1781530000766]